diff --git a/docs/fr/channels/matrix.md b/docs/fr/channels/matrix.md index b703d545b..110152fdb 100644 --- a/docs/fr/channels/matrix.md +++ b/docs/fr/channels/matrix.md @@ -1,29 +1,29 @@ --- read_when: - Configurer Matrix dans OpenClaw - - Configurer l'E2EE et la vérification de Matrix -summary: Statut de prise en charge de Matrix, configuration initiale et exemples de configuration + - Configurer le chiffrement de bout en bout et la vérification Matrix +summary: État de la prise en charge de Matrix, configuration et exemples de configuration title: Matrix x-i18n: - generated_at: "2026-04-09T01:29:57Z" + generated_at: "2026-04-15T06:56:36Z" model: gpt-5.4 provider: openai - source_hash: 28fc13c7620c1152200315ae69c94205da6de3180c53c814dd8ce03b5cb1758f + source_hash: 631f6fdcfebc23136c1a66b04851a25c047535d13cceba5650b8b421bc3afcf8 source_path: channels/matrix.md workflow: 15 --- # Matrix -Matrix est un plugin de canal intégré pour OpenClaw. -Il utilise le `matrix-js-sdk` officiel et prend en charge les DM, salons, fils, médias, réactions, sondages, localisation et l'E2EE. +Matrix est un Plugin de canal intégré pour OpenClaw. +Il utilise le `matrix-js-sdk` officiel et prend en charge les messages privés, les salons, les fils, les médias, les réactions, les sondages, la localisation et le chiffrement de bout en bout. ## Plugin intégré -Matrix est livré comme plugin intégré dans les versions actuelles d'OpenClaw, donc les -builds packagés normaux n'ont pas besoin d'une installation séparée. +Matrix est livré comme Plugin intégré dans les versions actuelles d’OpenClaw, donc les +builds packagées normales n’ont pas besoin d’une installation séparée. -Si vous utilisez une ancienne build ou une installation personnalisée qui exclut Matrix, installez-le +Si vous utilisez une build plus ancienne ou une installation personnalisée qui exclut Matrix, installez-le manuellement : Installer depuis npm : @@ -38,57 +38,57 @@ Installer depuis un checkout local : openclaw plugins install ./path/to/local/matrix-plugin ``` -Voir [Plugins](/fr/tools/plugin) pour le comportement des plugins et les règles d'installation. +Voir [Plugins](/fr/tools/plugin) pour le comportement des plugins et les règles d’installation. -## Configuration initiale +## Configuration -1. Assurez-vous que le plugin Matrix est disponible. - - Les versions packagées actuelles d'OpenClaw l'intègrent déjà. - - Les installations anciennes/personnalisées peuvent l'ajouter manuellement avec les commandes ci-dessus. +1. Assurez-vous que le Plugin Matrix est disponible. + - Les versions packagées actuelles d’OpenClaw l’intègrent déjà. + - Les installations plus anciennes/personnalisées peuvent l’ajouter manuellement avec les commandes ci-dessus. 2. Créez un compte Matrix sur votre homeserver. 3. Configurez `channels.matrix` avec soit : - `homeserver` + `accessToken`, soit - `homeserver` + `userId` + `password`. -4. Redémarrez la passerelle. -5. Démarrez un DM avec le bot ou invitez-le dans un salon. - - Les nouvelles invitations Matrix ne fonctionnent que lorsque `channels.matrix.autoJoin` les autorise. +4. Redémarrez la Gateway. +5. Démarrez un message privé avec le bot ou invitez-le dans un salon. + - Les nouvelles invitations Matrix ne fonctionnent que si `channels.matrix.autoJoin` les autorise. -Chemins de configuration interactive : +Chemins de configuration interactifs : ```bash openclaw channels add openclaw configure --section channels ``` -L'assistant Matrix demande : +L’assistant Matrix demande : -- l'URL du homeserver -- la méthode d'authentification : jeton d'accès ou mot de passe -- l'ID utilisateur (authentification par mot de passe uniquement) -- le nom d'appareil facultatif -- s'il faut activer l'E2EE -- s'il faut configurer l'accès aux salons et la jonction automatique sur invitation +- l’URL du homeserver +- la méthode d’authentification : jeton d’accès ou mot de passe +- l’ID utilisateur (authentification par mot de passe uniquement) +- le nom d’appareil facultatif +- s’il faut activer le chiffrement de bout en bout +- s’il faut configurer l’accès aux salons et la jonction automatique sur invitation -Comportements clés de l'assistant : +Comportements clés de l’assistant : -- Si les variables d'environnement d'authentification Matrix existent déjà et que ce compte n'a pas encore d'authentification enregistrée dans la configuration, l'assistant propose un raccourci env pour conserver l'authentification dans des variables d'environnement. -- Les noms de compte sont normalisés vers l'ID du compte. Par exemple, `Ops Bot` devient `ops-bot`. -- Les entrées de liste d'autorisation DM acceptent directement `@user:server` ; les noms d'affichage ne fonctionnent que lorsqu'une recherche en direct dans l'annuaire trouve une correspondance exacte unique. -- Les entrées de liste d'autorisation de salon acceptent directement les ID et alias de salon. Préférez `!room:server` ou `#alias:server` ; les noms non résolus sont ignorés à l'exécution lors de la résolution de la liste d'autorisation. -- En mode liste d'autorisation pour la jonction automatique sur invitation, utilisez uniquement des cibles d'invitation stables : `!roomId:server`, `#alias:server` ou `*`. Les noms de salon simples sont rejetés. -- Pour résoudre les noms de salon avant l'enregistrement, utilisez `openclaw channels resolve --channel matrix "Project Room"`. +- Si des variables d’environnement d’authentification Matrix existent déjà et que ce compte n’a pas déjà une authentification enregistrée dans la config, l’assistant propose un raccourci env pour conserver l’authentification dans les variables d’environnement. +- Les noms de compte sont normalisés vers l’ID du compte. Par exemple, `Ops Bot` devient `ops-bot`. +- Les entrées de liste d’autorisation des messages privés acceptent directement `@user:server` ; les noms d’affichage ne fonctionnent que lorsqu’une recherche en direct dans l’annuaire trouve une seule correspondance exacte. +- Les entrées de liste d’autorisation des salons acceptent directement les ID et alias de salon. Préférez `!room:server` ou `#alias:server` ; les noms non résolus sont ignorés à l’exécution par la résolution de la liste d’autorisation. +- En mode liste d’autorisation pour la jonction automatique sur invitation, utilisez uniquement des cibles d’invitation stables : `!roomId:server`, `#alias:server` ou `*`. Les noms de salon simples sont rejetés. +- Pour résoudre les noms de salon avant l’enregistrement, utilisez `openclaw channels resolve --channel matrix "Project Room"`. -`channels.matrix.autoJoin` a pour valeur par défaut `off`. +`channels.matrix.autoJoin` vaut par défaut `off`. -Si vous le laissez non défini, le bot ne rejoindra pas les salons invités ni les nouvelles invitations de type DM ; il n'apparaîtra donc pas dans les nouveaux groupes ou DM invités, sauf si vous le faites rejoindre manuellement d'abord. +Si vous ne le définissez pas, le bot ne rejoindra pas les salons invités ni les nouvelles invitations de type message privé ; il n’apparaîtra donc pas dans les nouveaux groupes ou messages privés invités, sauf si vous le faites rejoindre manuellement d’abord. -Définissez `autoJoin: "allowlist"` avec `autoJoinAllowlist` pour restreindre les invitations qu'il accepte, ou définissez `autoJoin: "always"` si vous voulez qu'il rejoigne chaque invitation. +Définissez `autoJoin: "allowlist"` avec `autoJoinAllowlist` pour restreindre les invitations qu’il accepte, ou définissez `autoJoin: "always"` si vous voulez qu’il rejoigne toutes les invitations. -En mode `allowlist`, `autoJoinAllowlist` accepte uniquement `!roomId:server`, `#alias:server` ou `*`. +En mode `allowlist`, `autoJoinAllowlist` n’accepte que `!roomId:server`, `#alias:server` ou `*`. -Exemple de liste d'autorisation : +Exemple de liste d’autorisation : ```json5 { @@ -106,7 +106,7 @@ Exemple de liste d'autorisation : } ``` -Rejoindre chaque invitation : +Rejoindre toutes les invitations : ```json5 { @@ -133,7 +133,7 @@ Configuration minimale basée sur un jeton : } ``` -Configuration basée sur un mot de passe (le jeton est mis en cache après la connexion) : +Configuration basée sur un mot de passe (le jeton est mis en cache après connexion) : ```json5 { @@ -151,9 +151,9 @@ Configuration basée sur un mot de passe (le jeton est mis en cache après la co Matrix stocke les identifiants mis en cache dans `~/.openclaw/credentials/matrix/`. Le compte par défaut utilise `credentials.json` ; les comptes nommés utilisent `credentials-.json`. -Lorsque des identifiants mis en cache existent à cet emplacement, OpenClaw considère Matrix comme configuré pour la configuration initiale, doctor et la découverte de l'état du canal, même si l'authentification actuelle n'est pas définie directement dans la configuration. +Lorsque des identifiants mis en cache existent à cet emplacement, OpenClaw considère Matrix comme configuré pour la configuration, doctor et la découverte de l’état des canaux, même si l’authentification actuelle n’est pas définie directement dans la config. -Équivalents en variables d'environnement (utilisés lorsque la clé de configuration n'est pas définie) : +Équivalents en variables d’environnement (utilisés lorsque la clé de config n’est pas définie) : - `MATRIX_HOMESERVER` - `MATRIX_ACCESS_TOKEN` @@ -162,7 +162,7 @@ Lorsque des identifiants mis en cache existent à cet emplacement, OpenClaw cons - `MATRIX_DEVICE_ID` - `MATRIX_DEVICE_NAME` -Pour les comptes non par défaut, utilisez des variables d'environnement limitées au compte : +Pour les comptes non par défaut, utilisez des variables d’environnement limitées au compte : - `MATRIX__HOMESERVER` - `MATRIX__ACCESS_TOKEN` @@ -176,19 +176,19 @@ Exemple pour le compte `ops` : - `MATRIX_OPS_HOMESERVER` - `MATRIX_OPS_ACCESS_TOKEN` -Pour l'ID de compte normalisé `ops-bot`, utilisez : +Pour l’ID de compte normalisé `ops-bot`, utilisez : - `MATRIX_OPS_X2D_BOT_HOMESERVER` - `MATRIX_OPS_X2D_BOT_ACCESS_TOKEN` -Matrix échappe la ponctuation dans les ID de compte afin d'éviter les collisions dans les variables d'environnement limitées au compte. -Par exemple, `-` devient `_X2D_`, donc `ops-prod` est mappé vers `MATRIX_OPS_X2D_PROD_*`. +Matrix échappe la ponctuation dans les ID de compte afin d’éviter les collisions dans les variables d’environnement limitées au compte. +Par exemple, `-` devient `_X2D_`, donc `ops-prod` devient `MATRIX_OPS_X2D_PROD_*`. -L'assistant interactif ne propose le raccourci par variable d'environnement que lorsque ces variables d'authentification sont déjà présentes et que le compte sélectionné n'a pas déjà d'authentification Matrix enregistrée dans la configuration. +L’assistant interactif ne propose le raccourci par variable d’environnement que lorsque ces variables d’environnement d’authentification sont déjà présentes et que le compte sélectionné n’a pas déjà une authentification Matrix enregistrée dans la config. ## Exemple de configuration -Il s'agit d'une configuration de base pratique avec appairage DM, liste d'autorisation de salon et E2EE activée : +Voici une configuration de base pratique avec appairage des messages privés, liste d’autorisation des salons et chiffrement de bout en bout activé : ```json5 { @@ -223,17 +223,17 @@ Il s'agit d'une configuration de base pratique avec appairage DM, liste d'autori } ``` -`autoJoin` s'applique à toutes les invitations Matrix, y compris aux invitations de type DM. OpenClaw ne peut pas -classifier de manière fiable un salon invité comme DM ou groupe au moment de l'invitation, donc toutes les invitations passent d'abord par `autoJoin`. -`dm.policy` s'applique après que le bot a rejoint le salon et que celui-ci a été classé comme DM. +`autoJoin` s’applique à toutes les invitations Matrix, y compris aux invitations de type message privé. OpenClaw ne peut pas +classifier de manière fiable un salon invité comme message privé ou groupe au moment de l’invitation, donc toutes les invitations passent d’abord par `autoJoin`. +`dm.policy` s’applique après que le bot a rejoint le salon et que celui-ci a été classé comme message privé. -## Aperçus de streaming +## Aperçus en streaming -Le streaming des réponses Matrix est activé sur demande. +Le streaming des réponses Matrix est optionnel. -Définissez `channels.matrix.streaming` sur `"partial"` lorsque vous voulez qu'OpenClaw envoie un seul aperçu en direct -de la réponse, modifie cet aperçu sur place pendant que le modèle génère le texte, puis le finalise lorsque la -réponse est terminée : +Définissez `channels.matrix.streaming` sur `"partial"` si vous voulez qu’OpenClaw envoie une seule +réponse d’aperçu en direct, modifie cet aperçu sur place pendant que le modèle génère du texte, puis le +finalise une fois la réponse terminée : ```json5 { @@ -245,36 +245,36 @@ réponse est terminée : } ``` -- `streaming: "off"` est la valeur par défaut. OpenClaw attend la réponse finale et l'envoie une seule fois. -- `streaming: "partial"` crée un message d'aperçu modifiable pour le bloc assistant en cours à l'aide de messages texte Matrix normaux. Cela préserve le comportement hérité de Matrix de notification sur le premier aperçu, donc les clients standards peuvent notifier sur le premier texte diffusé plutôt que sur le bloc terminé. -- `streaming: "quiet"` crée un aperçu discret modifiable pour le bloc assistant en cours. Utilisez-le uniquement si vous configurez aussi des règles push côté destinataire pour les modifications d'aperçu finalisées. -- `blockStreaming: true` active des messages de progression Matrix séparés. Avec le streaming d'aperçu activé, Matrix conserve le brouillon en direct pour le bloc actuel et préserve les blocs terminés comme messages séparés. -- Lorsque le streaming d'aperçu est activé et que `blockStreaming` est désactivé, Matrix modifie le brouillon en direct sur place et finalise ce même événement lorsque le bloc ou le tour se termine. -- Si l'aperçu ne tient plus dans un seul événement Matrix, OpenClaw arrête le streaming d'aperçu et revient à la livraison finale normale. -- Les réponses média envoient toujours normalement les pièces jointes. Si un aperçu obsolète ne peut plus être réutilisé en toute sécurité, OpenClaw le redacte avant d'envoyer la réponse média finale. -- Les modifications d'aperçu coûtent des appels supplémentaires à l'API Matrix. Laissez le streaming désactivé si vous voulez le comportement le plus conservateur vis-à-vis des limites de débit. +- `streaming: "off"` est la valeur par défaut. OpenClaw attend la réponse finale et l’envoie une seule fois. +- `streaming: "partial"` crée un message d’aperçu modifiable pour le bloc d’assistant en cours à l’aide de messages texte Matrix normaux. Cela préserve le comportement historique de Matrix où l’aperçu déclenche d’abord la notification, donc les clients standard peuvent notifier sur le premier texte d’aperçu diffusé au lieu du bloc terminé. +- `streaming: "quiet"` crée un aperçu discret modifiable pour le bloc d’assistant en cours. Utilisez-le uniquement si vous configurez aussi des règles push côté destinataire pour les modifications d’aperçu finalisées. +- `blockStreaming: true` active des messages de progression Matrix séparés. Avec le streaming d’aperçu activé, Matrix conserve le brouillon en direct pour le bloc actuel et garde les blocs terminés comme messages séparés. +- Lorsque le streaming d’aperçu est activé et que `blockStreaming` est désactivé, Matrix modifie le brouillon en direct sur place et finalise ce même événement lorsque le bloc ou le tour se termine. +- Si l’aperçu ne peut plus tenir dans un seul événement Matrix, OpenClaw arrête le streaming d’aperçu et revient à une livraison finale normale. +- Les réponses multimédias envoient toujours les pièces jointes normalement. Si un aperçu obsolète ne peut plus être réutilisé en toute sécurité, OpenClaw le rédige avant d’envoyer la réponse multimédia finale. +- Les modifications d’aperçu coûtent des appels supplémentaires à l’API Matrix. Laissez le streaming désactivé si vous voulez le comportement le plus prudent vis-à-vis de la limitation de débit. -`blockStreaming` n'active pas à lui seul les aperçus de brouillon. -Utilisez `streaming: "partial"` ou `streaming: "quiet"` pour les modifications d'aperçu ; ajoutez ensuite `blockStreaming: true` uniquement si vous voulez aussi que les blocs assistant terminés restent visibles comme messages de progression séparés. +`blockStreaming` n’active pas à lui seul les aperçus de brouillon. +Utilisez `streaming: "partial"` ou `streaming: "quiet"` pour les modifications d’aperçu ; ajoutez ensuite `blockStreaming: true` uniquement si vous voulez aussi que les blocs d’assistant terminés restent visibles comme messages de progression séparés. -Si vous avez besoin des notifications Matrix standards sans règles push personnalisées, utilisez `streaming: "partial"` pour le comportement de notification sur l'aperçu, ou laissez `streaming` désactivé pour une livraison finale uniquement. Avec `streaming: "off"` : +Si vous avez besoin des notifications Matrix standard sans règles push personnalisées, utilisez `streaming: "partial"` pour un comportement avec aperçu d’abord, ou laissez `streaming` désactivé pour un envoi final uniquement. Avec `streaming: "off"` : -- `blockStreaming: true` envoie chaque bloc terminé comme message Matrix normal avec notification. -- `blockStreaming: false` envoie uniquement la réponse finale terminée comme message Matrix normal avec notification. +- `blockStreaming: true` envoie chaque bloc terminé comme un message Matrix normal avec notification. +- `blockStreaming: false` envoie uniquement la réponse finale terminée comme un message Matrix normal avec notification. -### Règles push auto-hébergées pour les aperçus discrets finalisés +### Règles push auto-hébergées pour les aperçus finalisés discrets -Si vous exploitez votre propre infrastructure Matrix et voulez que les aperçus discrets ne notifient qu'une fois un bloc ou la -réponse finale terminés, définissez `streaming: "quiet"` et ajoutez une règle push par utilisateur pour les modifications d'aperçu finalisées. +Si vous exploitez votre propre infrastructure Matrix et que vous voulez que les aperçus discrets ne notifient que lorsqu’un bloc ou +une réponse finale est terminé, définissez `streaming: "quiet"` et ajoutez une règle push par utilisateur pour les modifications d’aperçu finalisées. -Il s'agit généralement d'une configuration côté utilisateur destinataire, et non d'un changement de configuration global du homeserver : +Il s’agit généralement d’une configuration côté utilisateur destinataire, pas d’un changement de config global du homeserver : -Récapitulatif rapide avant de commencer : +Correspondance rapide avant de commencer : - utilisateur destinataire = la personne qui doit recevoir la notification - utilisateur bot = le compte Matrix OpenClaw qui envoie la réponse -- utilisez le jeton d'accès de l'utilisateur destinataire pour les appels API ci-dessous -- faites correspondre `sender` dans la règle push avec le MXID complet de l'utilisateur bot +- utilisez le jeton d’accès de l’utilisateur destinataire pour les appels API ci-dessous +- faites correspondre `sender` dans la règle push avec le MXID complet de l’utilisateur bot 1. Configurez OpenClaw pour utiliser des aperçus discrets : @@ -288,13 +288,13 @@ Récapitulatif rapide avant de commencer : } ``` -2. Assurez-vous que le compte destinataire reçoit déjà les notifications push Matrix normales. Les - règles d'aperçu discret ne fonctionnent que si cet utilisateur a déjà des pushers/appareils opérationnels. +2. Assurez-vous que le compte destinataire reçoit déjà les notifications push Matrix normales. Les règles + d’aperçu discret ne fonctionnent que si cet utilisateur a déjà des pushers/appareils fonctionnels. -3. Obtenez le jeton d'accès de l'utilisateur destinataire. - - Utilisez le jeton de l'utilisateur qui reçoit, pas celui du bot. +3. Obtenez le jeton d’accès de l’utilisateur destinataire. + - Utilisez le jeton de l’utilisateur qui reçoit les messages, pas celui du bot. - Réutiliser un jeton de session client existant est généralement le plus simple. - - Si vous devez générer un nouveau jeton, vous pouvez vous connecter via l'API Client-Server Matrix standard : + - Si vous devez créer un nouveau jeton, vous pouvez vous connecter via l’API Client-Server Matrix standard : ```bash curl -sS -X POST \ @@ -318,10 +318,10 @@ curl -sS \ "https://matrix.example.org/_matrix/client/v3/pushers" ``` -Si cette commande ne renvoie aucun pusher/appareil actif, corrigez d'abord les notifications Matrix normales avant d'ajouter la +Si cela ne renvoie aucun pusher/appareil actif, corrigez d’abord les notifications Matrix normales avant d’ajouter la règle OpenClaw ci-dessous. -OpenClaw marque les modifications d'aperçu finalisées en texte seul avec : +OpenClaw marque les modifications d’aperçu finalisées contenant uniquement du texte avec : ```json { @@ -329,7 +329,7 @@ OpenClaw marque les modifications d'aperçu finalisées en texte seul avec : } ``` -5. Créez une règle push de type override pour chaque compte destinataire qui doit recevoir ces notifications : +5. Créez une règle push de remplacement pour chaque compte destinataire qui doit recevoir ces notifications : ```bash curl -sS -X PUT \ @@ -359,22 +359,22 @@ curl -sS -X PUT \ }' ``` -Remplacez ces valeurs avant d'exécuter la commande : +Remplacez ces valeurs avant d’exécuter la commande : -- `https://matrix.example.org` : l'URL de base de votre homeserver -- `$USER_ACCESS_TOKEN` : le jeton d'accès de l'utilisateur destinataire +- `https://matrix.example.org` : l’URL de base de votre homeserver +- `$USER_ACCESS_TOKEN` : le jeton d’accès de l’utilisateur qui reçoit les messages - `openclaw-finalized-preview-botname` : un ID de règle unique à ce bot pour cet utilisateur destinataire -- `@bot:example.org` : le MXID de votre bot Matrix OpenClaw, pas le MXID de l'utilisateur destinataire +- `@bot:example.org` : le MXID de votre bot Matrix OpenClaw, pas celui de l’utilisateur destinataire -Important pour les configurations multi-bots : +Important pour les configurations avec plusieurs bots : -- Les règles push sont indexées par `ruleId`. Réexécuter `PUT` sur le même ID de règle met à jour cette même règle. -- Si un utilisateur destinataire doit recevoir des notifications de plusieurs comptes bot Matrix OpenClaw, créez une règle par bot avec un ID de règle unique pour chaque correspondance d'expéditeur. -- Un modèle simple est `openclaw-finalized-preview-`, par exemple `openclaw-finalized-preview-ops` ou `openclaw-finalized-preview-support`. +- Les règles push sont indexées par `ruleId`. Réexécuter `PUT` avec le même ID de règle met à jour cette règle. +- Si un même utilisateur destinataire doit recevoir des notifications pour plusieurs comptes bot Matrix OpenClaw, créez une règle par bot avec un ID de règle unique pour chaque correspondance `sender`. +- Un schéma simple consiste à utiliser `openclaw-finalized-preview-`, par exemple `openclaw-finalized-preview-ops` ou `openclaw-finalized-preview-support`. -La règle est évaluée par rapport à l'expéditeur de l'événement : +La règle est évaluée par rapport à l’expéditeur de l’événement : -- authentifiez-vous avec le jeton de l'utilisateur destinataire +- authentifiez-vous avec le jeton de l’utilisateur destinataire - faites correspondre `sender` avec le MXID du bot OpenClaw 6. Vérifiez que la règle existe : @@ -385,10 +385,10 @@ curl -sS \ "https://matrix.example.org/_matrix/client/v3/pushrules/global/override/openclaw-finalized-preview-botname" ``` -7. Testez une réponse diffusée. En mode discret, le salon doit afficher un brouillon d'aperçu discret et la - modification finale sur place doit notifier une fois le bloc ou le tour terminé. +7. Testez une réponse diffusée en streaming. En mode discret, le salon doit afficher un aperçu de brouillon discret et la + modification finale sur place doit envoyer une notification une fois le bloc ou le tour terminé. -Si vous devez supprimer la règle plus tard, supprimez ce même ID de règle avec le jeton de l'utilisateur destinataire : +Si vous devez supprimer la règle plus tard, supprimez ce même ID de règle avec le jeton de l’utilisateur destinataire : ```bash curl -sS -X DELETE \ @@ -398,33 +398,33 @@ curl -sS -X DELETE \ Remarques : -- Créez la règle avec le jeton d'accès de l'utilisateur destinataire, pas celui du bot. -- Les nouvelles règles `override` définies par l'utilisateur sont insérées avant les règles de suppression par défaut, donc aucun paramètre d'ordre supplémentaire n'est nécessaire. -- Cela n'affecte que les modifications d'aperçu en texte seul qu'OpenClaw peut finaliser en place en toute sécurité. Les replis pour médias et aperçus obsolètes utilisent toujours la livraison Matrix normale. -- Si `GET /_matrix/client/v3/pushers` n'affiche aucun pusher, l'utilisateur ne dispose pas encore d'une livraison push Matrix fonctionnelle pour ce compte/appareil. +- Créez la règle avec le jeton d’accès de l’utilisateur destinataire, pas celui du bot. +- Les nouvelles règles `override` définies par l’utilisateur sont insérées avant les règles de suppression par défaut ; aucun paramètre d’ordre supplémentaire n’est donc nécessaire. +- Cela n’affecte que les modifications d’aperçu contenant uniquement du texte qu’OpenClaw peut finaliser en toute sécurité sur place. Les replis média et les replis d’aperçu obsolète utilisent toujours la livraison Matrix normale. +- Si `GET /_matrix/client/v3/pushers` n’affiche aucun pusher, l’utilisateur ne dispose pas encore d’une livraison push Matrix fonctionnelle pour ce compte/appareil. #### Synapse -Pour Synapse, la configuration ci-dessus est généralement suffisante à elle seule : +Pour Synapse, la configuration ci-dessus suffit généralement à elle seule : -- Aucun changement spécial dans `homeserver.yaml` n'est requis pour les notifications d'aperçu OpenClaw finalisé. -- Si votre déploiement Synapse envoie déjà les notifications push Matrix normales, le jeton utilisateur + l'appel `pushrules` ci-dessus constituent l'étape principale de configuration. -- Si vous exécutez Synapse derrière un proxy inverse ou des workers, assurez-vous que `/_matrix/client/.../pushrules/` atteint correctement Synapse. -- Si vous utilisez des workers Synapse, assurez-vous que les pushers sont sains. La livraison push est gérée par le processus principal ou par `synapse.app.pusher` / les workers pusher configurés. +- Aucune modification spéciale de `homeserver.yaml` n’est requise pour les notifications d’aperçu OpenClaw finalisées. +- Si votre déploiement Synapse envoie déjà des notifications push Matrix normales, le jeton utilisateur + l’appel `pushrules` ci-dessus constituent l’étape principale de configuration. +- Si vous exécutez Synapse derrière un reverse proxy ou des workers, assurez-vous que `/_matrix/client/.../pushrules/` atteint correctement Synapse. +- Si vous utilisez des workers Synapse, assurez-vous que les pushers sont en bon état. La livraison push est gérée par le processus principal ou par `synapse.app.pusher` / les workers pusher configurés. #### Tuwunel -Pour Tuwunel, utilisez le même flux de configuration et le même appel d'API `pushrules` que ci-dessus : +Pour Tuwunel, utilisez le même flux de configuration et le même appel API `pushrules` que ci-dessus : -- Aucune configuration spécifique à Tuwunel n'est requise pour le marqueur d'aperçu finalisé lui-même. -- Si les notifications Matrix normales fonctionnent déjà pour cet utilisateur, le jeton utilisateur + l'appel `pushrules` ci-dessus constituent l'étape principale de configuration. -- Si les notifications semblent disparaître pendant que l'utilisateur est actif sur un autre appareil, vérifiez si `suppress_push_when_active` est activé. Tuwunel a ajouté cette option dans Tuwunel 1.4.2 le 12 septembre 2025, et elle peut volontairement supprimer les push vers d'autres appareils pendant qu'un appareil est actif. +- Aucune configuration spécifique à Tuwunel n’est requise pour le marqueur d’aperçu finalisé lui-même. +- Si les notifications Matrix normales fonctionnent déjà pour cet utilisateur, le jeton utilisateur + l’appel `pushrules` ci-dessus constituent l’étape principale de configuration. +- Si les notifications semblent disparaître pendant que l’utilisateur est actif sur un autre appareil, vérifiez si `suppress_push_when_active` est activé. Tuwunel a ajouté cette option dans Tuwunel 1.4.2 le 12 septembre 2025, et elle peut volontairement supprimer les pushs vers d’autres appareils lorsqu’un appareil est actif. ## Salons bot à bot -Par défaut, les messages Matrix provenant d'autres comptes Matrix OpenClaw configurés sont ignorés. +Par défaut, les messages Matrix provenant d’autres comptes Matrix OpenClaw configurés sont ignorés. -Utilisez `allowBots` lorsque vous voulez volontairement autoriser le trafic Matrix inter-agents : +Utilisez `allowBots` lorsque vous voulez intentionnellement autoriser le trafic Matrix inter-agent : ```json5 { @@ -441,17 +441,17 @@ Utilisez `allowBots` lorsque vous voulez volontairement autoriser le trafic Matr } ``` -- `allowBots: true` accepte les messages d'autres comptes bot Matrix configurés dans les salons et DM autorisés. -- `allowBots: "mentions"` n'accepte ces messages que lorsqu'ils mentionnent visiblement ce bot dans les salons. Les DM restent autorisés. -- `groups..allowBots` remplace le paramètre au niveau du compte pour un salon. -- OpenClaw ignore toujours les messages provenant du même ID utilisateur Matrix afin d'éviter les boucles d'auto-réponse. -- Matrix n'expose pas ici de drapeau bot natif ; OpenClaw considère « rédigé par un bot » comme « envoyé par un autre compte Matrix configuré sur cette passerelle OpenClaw ». +- `allowBots: true` accepte les messages provenant d’autres comptes bot Matrix configurés dans les salons et messages privés autorisés. +- `allowBots: "mentions"` accepte ces messages uniquement lorsqu’ils mentionnent visiblement ce bot dans les salons. Les messages privés restent autorisés. +- `groups..allowBots` remplace le paramètre au niveau du compte pour un salon donné. +- OpenClaw ignore toujours les messages provenant du même ID utilisateur Matrix afin d’éviter les boucles d’auto-réponse. +- Matrix n’expose pas ici d’indicateur natif de bot ; OpenClaw considère « écrit par un bot » comme « envoyé par un autre compte Matrix configuré sur cette Gateway OpenClaw ». -Utilisez des listes d'autorisation strictes pour les salons et des obligations de mention lorsque vous activez le trafic bot à bot dans des salons partagés. +Utilisez des listes d’autorisation de salon strictes et des exigences de mention lorsque vous activez le trafic bot à bot dans des salons partagés. ## Chiffrement et vérification -Dans les salons chiffrés (E2EE), les événements d'image sortants utilisent `thumbnail_file` afin que les aperçus d'image soient chiffrés avec la pièce jointe complète. Les salons non chiffrés utilisent toujours `thumbnail_url` en clair. Aucune configuration n'est nécessaire — le plugin détecte automatiquement l'état E2EE. +Dans les salons chiffrés (E2EE), les événements d’image sortants utilisent `thumbnail_file` afin que les aperçus d’image soient chiffrés en même temps que la pièce jointe complète. Les salons non chiffrés utilisent toujours `thumbnail_url` en clair. Aucune configuration n’est nécessaire — le Plugin détecte automatiquement l’état E2EE. Activer le chiffrement : @@ -469,37 +469,37 @@ Activer le chiffrement : } ``` -Vérifier l'état de la vérification : +Vérifier l’état de la vérification : ```bash openclaw matrix verify status ``` -État verbeux (diagnostics complets) : +État détaillé (diagnostics complets) : ```bash openclaw matrix verify status --verbose ``` -Inclure la clé de récupération stockée dans une sortie lisible par machine : +Inclure la clé de récupération stockée dans la sortie lisible par machine : ```bash openclaw matrix verify status --include-recovery-key --json ``` -Initialiser l'état de cross-signing et de vérification : +Initialiser l’état de cross-signing et de vérification : ```bash openclaw matrix verify bootstrap ``` -Diagnostics détaillés de l'initialisation : +Diagnostics détaillés de l’initialisation : ```bash openclaw matrix verify bootstrap --verbose ``` -Forcer une réinitialisation fraîche de l'identité de cross-signing avant l'initialisation : +Forcer une réinitialisation complète de l’identité de cross-signing avant l’initialisation : ```bash openclaw matrix verify bootstrap --force-reset-cross-signing @@ -511,19 +511,19 @@ Vérifier cet appareil avec une clé de récupération : openclaw matrix verify device "" ``` -Détails verbeux de la vérification de l'appareil : +Détails détaillés de la vérification de l’appareil : ```bash openclaw matrix verify device "" --verbose ``` -Vérifier l'état de santé de la sauvegarde des clés de salon : +Vérifier l’état de santé de la sauvegarde des clés de salon : ```bash openclaw matrix verify backup status ``` -Diagnostics détaillés de l'état de santé de la sauvegarde : +Diagnostics détaillés de l’état de santé de la sauvegarde : ```bash openclaw matrix verify backup status --verbose @@ -541,20 +541,20 @@ Diagnostics détaillés de la restauration : openclaw matrix verify backup restore --verbose ``` -Supprimer la sauvegarde serveur actuelle et créer une nouvelle base de sauvegarde. Si la -clé de sauvegarde stockée ne peut pas être chargée proprement, cette réinitialisation peut aussi recréer le stockage secret afin que +Supprimer la sauvegarde serveur actuelle et créer une nouvelle base de référence de sauvegarde. Si la +clé de sauvegarde stockée ne peut pas être chargée proprement, cette réinitialisation peut aussi recréer le stockage de secrets afin que les futurs démarrages à froid puissent charger la nouvelle clé de sauvegarde : ```bash openclaw matrix verify backup reset --yes ``` -Toutes les commandes `verify` sont concises par défaut (y compris la journalisation interne discrète du SDK) et n'affichent des diagnostics détaillés qu'avec `--verbose`. +Toutes les commandes `verify` sont concises par défaut (y compris la journalisation interne discrète du SDK) et n’affichent des diagnostics détaillés qu’avec `--verbose`. Utilisez `--json` pour une sortie complète lisible par machine dans les scripts. -Dans les configurations multi-comptes, les commandes CLI Matrix utilisent le compte Matrix par défaut implicite, sauf si vous passez `--account `. -Si vous configurez plusieurs comptes nommés, définissez d'abord `channels.matrix.defaultAccount`, sinon ces opérations CLI implicites s'arrêteront et vous demanderont de choisir explicitement un compte. -Utilisez `--account` chaque fois que vous voulez que les opérations de vérification ou d'appareil ciblent explicitement un compte nommé : +Dans les configurations multi-comptes, les commandes Matrix CLI utilisent le compte Matrix par défaut implicite sauf si vous passez `--account `. +Si vous configurez plusieurs comptes nommés, définissez d’abord `channels.matrix.defaultAccount`, sinon ces opérations CLI implicites s’arrêteront et vous demanderont de choisir explicitement un compte. +Utilisez `--account` chaque fois que vous voulez que les opérations de vérification ou d’appareil ciblent explicitement un compte nommé : ```bash openclaw matrix verify status --account assistant @@ -562,43 +562,43 @@ openclaw matrix verify backup restore --account assistant openclaw matrix devices list --account assistant ``` -Lorsque le chiffrement est désactivé ou indisponible pour un compte nommé, les avertissements Matrix et les erreurs de vérification pointent vers la clé de configuration de ce compte, par exemple `channels.matrix.accounts.assistant.encryption`. +Lorsque le chiffrement est désactivé ou indisponible pour un compte nommé, les avertissements Matrix et les erreurs de vérification pointent vers la clé de config de ce compte, par exemple `channels.matrix.accounts.assistant.encryption`. ### Ce que signifie « vérifié » -OpenClaw considère cet appareil Matrix comme vérifié uniquement lorsqu'il est vérifié par votre propre identité de cross-signing. +OpenClaw considère cet appareil Matrix comme vérifié uniquement lorsqu’il est vérifié par votre propre identité de cross-signing. En pratique, `openclaw matrix verify status --verbose` expose trois signaux de confiance : -- `Locally trusted` : cet appareil n'est approuvé que par le client actuel -- `Cross-signing verified` : le SDK signale l'appareil comme vérifié via le cross-signing -- `Signed by owner` : l'appareil est signé par votre propre clé d'auto-signature +- `Locally trusted` : cet appareil n’est approuvé que par le client actuel +- `Cross-signing verified` : le SDK indique que l’appareil est vérifié via le cross-signing +- `Signed by owner` : l’appareil est signé par votre propre clé d’auto-signature -`Verified by owner` devient `yes` uniquement lorsqu'une vérification par cross-signing ou une signature par le propriétaire est présente. -La confiance locale seule ne suffit pas pour qu'OpenClaw traite l'appareil comme entièrement vérifié. +`Verified by owner` devient `yes` uniquement lorsque la vérification par cross-signing ou la signature du propriétaire est présente. +La confiance locale seule ne suffit pas pour qu’OpenClaw considère l’appareil comme entièrement vérifié. -### Ce que fait l'initialisation +### Ce que fait l’initialisation -`openclaw matrix verify bootstrap` est la commande de réparation et de configuration des comptes Matrix chiffrés. -Elle effectue tout ce qui suit dans cet ordre : +`openclaw matrix verify bootstrap` est la commande de réparation et de configuration pour les comptes Matrix chiffrés. +Elle effectue toutes les opérations suivantes dans l’ordre : -- initialise le stockage secret, en réutilisant une clé de récupération existante lorsque c'est possible +- initialise le stockage de secrets, en réutilisant une clé de récupération existante lorsque c’est possible - initialise le cross-signing et téléverse les clés publiques de cross-signing manquantes -- tente de marquer et de signer en cross-signing l'appareil actuel -- crée une nouvelle sauvegarde côté serveur des clés de salon si aucune n'existe déjà +- tente de marquer et de signer par cross-signing l’appareil actuel +- crée une nouvelle sauvegarde serveur des clés de salon si elle n’existe pas déjà -Si le homeserver exige une authentification interactive pour téléverser les clés de cross-signing, OpenClaw essaie d'abord le téléversement sans authentification, puis avec `m.login.dummy`, puis avec `m.login.password` lorsque `channels.matrix.password` est configuré. +Si le homeserver exige une authentification interactive pour téléverser les clés de cross-signing, OpenClaw tente d’abord le téléversement sans authentification, puis avec `m.login.dummy`, puis avec `m.login.password` lorsque `channels.matrix.password` est configuré. -Utilisez `--force-reset-cross-signing` uniquement lorsque vous voulez délibérément abandonner l'identité actuelle de cross-signing et en créer une nouvelle. +Utilisez `--force-reset-cross-signing` uniquement si vous voulez intentionnellement supprimer l’identité de cross-signing actuelle et en créer une nouvelle. -Si vous voulez délibérément abandonner la sauvegarde actuelle des clés de salon et démarrer une nouvelle -base de sauvegarde pour les futurs messages, utilisez `openclaw matrix verify backup reset --yes`. -Ne faites cela que si vous acceptez que l'ancien historique chiffré irrécupérable reste -indisponible et qu'OpenClaw puisse recréer le stockage secret si le secret de sauvegarde actuel +Si vous voulez intentionnellement supprimer la sauvegarde actuelle des clés de salon et démarrer une nouvelle +base de référence de sauvegarde pour les futurs messages, utilisez `openclaw matrix verify backup reset --yes`. +Faites-le uniquement si vous acceptez que l’ancien historique chiffré irrécupérable reste +indisponible et qu’OpenClaw puisse recréer le stockage de secrets si le secret de sauvegarde actuel ne peut pas être chargé en toute sécurité. -### Nouvelle base de sauvegarde +### Nouvelle base de référence de sauvegarde -Si vous voulez continuer à faire fonctionner les futurs messages chiffrés et acceptez de perdre l'ancien historique irrécupérable, exécutez ces commandes dans l'ordre : +Si vous voulez conserver le fonctionnement des futurs messages chiffrés et acceptez de perdre l’ancien historique irrécupérable, exécutez ces commandes dans l’ordre : ```bash openclaw matrix verify backup reset --yes @@ -606,71 +606,71 @@ openclaw matrix verify backup status --verbose openclaw matrix verify status ``` -Ajoutez `--account ` à chaque commande si vous voulez cibler explicitement un compte Matrix nommé. +Ajoutez `--account ` à chaque commande lorsque vous voulez cibler explicitement un compte Matrix nommé. ### Comportement au démarrage Lorsque `encryption: true`, Matrix définit par défaut `startupVerification` sur `"if-unverified"`. -Au démarrage, si cet appareil n'est toujours pas vérifié, Matrix demandera une auto-vérification dans un autre client Matrix, -évitera les demandes en double lorsqu'une demande est déjà en attente, et appliquera un délai local avant de réessayer après des redémarrages. -Les tentatives de demande échouées sont réessayées plus rapidement que la création réussie d'une demande, par défaut. +Au démarrage, si cet appareil n’est toujours pas vérifié, Matrix demandera une auto-vérification dans un autre client Matrix, +évitera les demandes en double tant qu’une demande est déjà en attente, et appliquera un délai d’attente local avant de réessayer après les redémarrages. +Les tentatives de demande échouées sont réessayées plus rapidement que la création réussie d’une demande, par défaut. Définissez `startupVerification: "off"` pour désactiver les demandes automatiques au démarrage, ou ajustez `startupVerificationCooldownHours` -si vous voulez une fenêtre de nouvelle tentative plus courte ou plus longue. +si vous voulez une fenêtre de réessai plus courte ou plus longue. -Le démarrage effectue aussi automatiquement une passe conservatrice d'initialisation crypto. -Cette passe essaie d'abord de réutiliser le stockage secret actuel et l'identité de cross-signing existante, et évite de réinitialiser le cross-signing sauf si vous exécutez un flux explicite de réparation par initialisation. +Le démarrage effectue également automatiquement un passage conservateur d’initialisation crypto. +Ce passage essaie d’abord de réutiliser le stockage de secrets et l’identité de cross-signing actuels, et évite de réinitialiser le cross-signing à moins que vous n’exécutiez un flux explicite de réparation par initialisation. -Si le démarrage trouve un état d'initialisation cassé et que `channels.matrix.password` est configuré, OpenClaw peut tenter un chemin de réparation plus strict. -Si l'appareil actuel est déjà signé par le propriétaire, OpenClaw préserve cette identité au lieu de la réinitialiser automatiquement. +Si le démarrage détecte un état d’initialisation défaillant et que `channels.matrix.password` est configuré, OpenClaw peut tenter un chemin de réparation plus strict. +Si l’appareil actuel est déjà signé par le propriétaire, OpenClaw préserve cette identité au lieu de la réinitialiser automatiquement. -Voir [Migration Matrix](/fr/install/migrating-matrix) pour le flux complet de mise à niveau, les limites, les commandes de récupération et les messages de migration courants. +Voir [migration Matrix](/fr/install/migrating-matrix) pour le flux complet de mise à niveau, les limites, les commandes de récupération et les messages de migration courants. ### Avis de vérification -Matrix publie directement dans le DM strict de vérification des avis sur le cycle de vie de la vérification sous forme de messages `m.notice`. +Matrix publie les avis du cycle de vie de la vérification directement dans le message privé strict de vérification sous forme de messages `m.notice`. Cela inclut : - les avis de demande de vérification -- les avis de vérification prête (avec des instructions explicites « Vérifier par emoji ») -- les avis de début et de fin de vérification -- les détails SAS (emoji et décimaux) lorsqu'ils sont disponibles +- les avis de vérification prête (avec des instructions explicites « Verify by emoji ») +- le début et la fin de la vérification +- les détails SAS (emoji et décimaux) lorsqu’ils sont disponibles -Les demandes de vérification entrantes provenant d'un autre client Matrix sont suivies et automatiquement acceptées par OpenClaw. -Pour les flux d'auto-vérification, OpenClaw démarre aussi automatiquement le flux SAS lorsque la vérification par emoji devient disponible et confirme son propre côté. -Pour les demandes de vérification provenant d'un autre utilisateur/appareil Matrix, OpenClaw accepte automatiquement la demande puis attend que le flux SAS se poursuive normalement. -Vous devez toujours comparer les emoji ou la SAS décimale dans votre client Matrix et confirmer « They match » là-bas pour terminer la vérification. +Les demandes de vérification entrantes provenant d’un autre client Matrix sont suivies et automatiquement acceptées par OpenClaw. +Pour les flux d’auto-vérification, OpenClaw démarre également automatiquement le flux SAS lorsque la vérification par emoji devient disponible et confirme son propre côté. +Pour les demandes de vérification provenant d’un autre utilisateur/appareil Matrix, OpenClaw accepte automatiquement la demande puis attend que le flux SAS se poursuive normalement. +Vous devez toujours comparer les emoji ou le SAS décimal dans votre client Matrix et confirmer « They match » là-bas pour terminer la vérification. -OpenClaw n'accepte pas automatiquement à l'aveugle les flux en double initiés par lui-même. Au démarrage, il évite de créer une nouvelle demande lorsqu'une auto-vérification est déjà en attente. +OpenClaw n’accepte pas automatiquement à l’aveugle les flux dupliqués auto-initiés. Au démarrage, il évite de créer une nouvelle demande lorsqu’une demande d’auto-vérification est déjà en attente. -Les avis de vérification protocole/système ne sont pas transférés au pipeline de chat de l'agent, donc ils ne produisent pas `NO_REPLY`. +Les avis de vérification de protocole/système ne sont pas transmis au pipeline de chat de l’agent, donc ils ne produisent pas `NO_REPLY`. ### Hygiène des appareils -Les anciens appareils Matrix gérés par OpenClaw peuvent s'accumuler sur le compte et rendre la confiance dans les salons chiffrés plus difficile à interpréter. +Les anciens appareils Matrix gérés par OpenClaw peuvent s’accumuler sur le compte et rendre la confiance dans les salons chiffrés plus difficile à interpréter. Listez-les avec : ```bash openclaw matrix devices list ``` -Supprimez les appareils Matrix obsolètes gérés par OpenClaw avec : +Supprimez les appareils OpenClaw gérés devenus obsolètes avec : ```bash openclaw matrix devices prune-stale ``` -### Magasin crypto +### Stockage crypto -L'E2EE Matrix utilise le chemin crypto Rust officiel de `matrix-js-sdk` dans Node, avec `fake-indexeddb` comme shim IndexedDB. L'état crypto est persisté dans un fichier snapshot (`crypto-idb-snapshot.json`) et restauré au démarrage. Le fichier snapshot est un état d'exécution sensible stocké avec des permissions de fichier restrictives. +Le chiffrement de bout en bout Matrix utilise le chemin crypto Rust officiel de `matrix-js-sdk` dans Node, avec `fake-indexeddb` comme shim IndexedDB. L’état crypto est conservé dans un fichier d’instantané (`crypto-idb-snapshot.json`) et restauré au démarrage. Le fichier d’instantané est un état d’exécution sensible stocké avec des permissions de fichier restrictives. -L'état d'exécution chiffré est stocké sous des racines par compte, par utilisateur et par hachage de jeton dans +L’état d’exécution chiffré se trouve sous des racines par compte, par utilisateur et par hachage de jeton dans `~/.openclaw/matrix/accounts//__//`. Ce répertoire contient le magasin de synchronisation (`bot-storage.json`), le magasin crypto (`crypto/`), -le fichier de clé de récupération (`recovery-key.json`), le snapshot IndexedDB (`crypto-idb-snapshot.json`), -les liaisons de fils (`thread-bindings.json`) et l'état de vérification au démarrage (`startup-verification.json`). -Lorsque le jeton change mais que l'identité du compte reste la même, OpenClaw réutilise la meilleure -racine existante pour ce triplet compte/homeserver/utilisateur afin que l'état de synchronisation précédent, l'état crypto, les liaisons de fils -et l'état de vérification au démarrage restent visibles. +le fichier de clé de récupération (`recovery-key.json`), l’instantané IndexedDB (`crypto-idb-snapshot.json`), +les associations de fils (`thread-bindings.json`) et l’état de vérification au démarrage (`startup-verification.json`). +Lorsque le jeton change mais que l’identité du compte reste la même, OpenClaw réutilise la meilleure racine existante +pour ce tuple compte/homeserver/utilisateur afin que l’état de synchronisation antérieur, l’état crypto, les associations de fils +et l’état de vérification au démarrage restent visibles. ## Gestion du profil @@ -681,49 +681,49 @@ openclaw matrix profile set --name "OpenClaw Assistant" openclaw matrix profile set --avatar-url https://cdn.example.org/avatar.png ``` -Ajoutez `--account ` si vous voulez cibler explicitement un compte Matrix nommé. +Ajoutez `--account ` lorsque vous voulez cibler explicitement un compte Matrix nommé. -Matrix accepte directement les URL d'avatar `mxc://`. Lorsque vous passez une URL d'avatar `http://` ou `https://`, OpenClaw la téléverse d'abord dans Matrix et réécrit l'URL `mxc://` résolue dans `channels.matrix.avatarUrl` (ou la surcharge du compte sélectionné). +Matrix accepte directement les URL d’avatar `mxc://`. Lorsque vous transmettez une URL d’avatar `http://` ou `https://`, OpenClaw la téléverse d’abord vers Matrix puis enregistre l’URL `mxc://` résolue dans `channels.matrix.avatarUrl` (ou dans la surcharge du compte sélectionné). ## Fils -Matrix prend en charge les fils Matrix natifs à la fois pour les réponses automatiques et les envois via l'outil de message. +Matrix prend en charge les fils Matrix natifs à la fois pour les réponses automatiques et pour les envois de l’outil de message. -- `dm.sessionScope: "per-user"` (par défaut) conserve le routage des DM Matrix limité à l'expéditeur, de sorte que plusieurs salons DM peuvent partager une session lorsqu'ils se résolvent vers le même pair. -- `dm.sessionScope: "per-room"` isole chaque salon DM Matrix dans sa propre clé de session tout en utilisant les contrôles normaux d'authentification DM et de liste d'autorisation. -- Les liaisons explicites de conversation Matrix priment toujours sur `dm.sessionScope`, donc les salons et fils liés conservent la session cible choisie. -- `threadReplies: "off"` conserve les réponses au niveau supérieur et garde les messages entrants en fil sur la session parente. -- `threadReplies: "inbound"` répond dans un fil uniquement lorsque le message entrant se trouvait déjà dans ce fil. -- `threadReplies: "always"` conserve les réponses de salon dans un fil enraciné sur le message déclencheur et route cette conversation via la session limitée au fil correspondante dès le premier message déclencheur. -- `dm.threadReplies` remplace le paramètre de niveau supérieur pour les DM uniquement. Par exemple, vous pouvez isoler les fils des salons tout en gardant les DM à plat. -- Les messages entrants en fil incluent le message racine du fil comme contexte supplémentaire pour l'agent. -- Les envois via l'outil de message héritent automatiquement du fil Matrix actuel lorsque la cible est le même salon, ou la même cible utilisateur DM, sauf si un `threadId` explicite est fourni. -- La réutilisation d'une même session ciblée par utilisateur DM n'intervient que lorsque les métadonnées de la session actuelle prouvent le même pair DM sur le même compte Matrix ; sinon OpenClaw revient au routage normal limité à l'utilisateur. -- Lorsqu'OpenClaw détecte qu'un salon DM Matrix entre en collision avec un autre salon DM sur la même session DM Matrix partagée, il publie une unique `m.notice` dans ce salon avec l'échappatoire `/focus` lorsque les liaisons de fils sont activées et l'indication `dm.sessionScope`. -- Les liaisons de fils d'exécution sont prises en charge pour Matrix. `/focus`, `/unfocus`, `/agents`, `/session idle`, `/session max-age` et `/acp spawn` lié à un fil fonctionnent dans les salons et DM Matrix. -- Le `/focus` Matrix de niveau supérieur dans un salon/DM crée un nouveau fil Matrix et le lie à la session cible lorsque `threadBindings.spawnSubagentSessions=true`. -- Exécuter `/focus` ou `/acp spawn --thread here` dans un fil Matrix existant lie plutôt ce fil actuel. +- `dm.sessionScope: "per-user"` (par défaut) conserve le routage des messages privés Matrix au niveau de l’expéditeur, de sorte que plusieurs salons de message privé peuvent partager une même session lorsqu’ils se résolvent vers le même pair. +- `dm.sessionScope: "per-room"` isole chaque salon de message privé Matrix dans sa propre clé de session tout en utilisant les vérifications normales d’authentification et de liste d’autorisation des messages privés. +- Les associations de conversation Matrix explicites restent prioritaires sur `dm.sessionScope`, donc les salons et fils associés conservent leur session cible choisie. +- `threadReplies: "off"` conserve les réponses au niveau supérieur et laisse les messages entrants en fil sur la session parente. +- `threadReplies: "inbound"` répond dans un fil uniquement lorsque le message entrant était déjà dans ce fil. +- `threadReplies: "always"` conserve les réponses de salon dans un fil enraciné sur le message déclencheur et fait passer cette conversation par la session à portée de fil correspondante dès le premier message déclencheur. +- `dm.threadReplies` remplace le paramètre de niveau supérieur pour les messages privés uniquement. Par exemple, vous pouvez garder les fils de salon isolés tout en gardant les messages privés à plat. +- Les messages entrants en fil incluent le message racine du fil comme contexte supplémentaire pour l’agent. +- Les envois de l’outil de message héritent automatiquement du fil Matrix actuel lorsque la cible est le même salon, ou le même utilisateur cible en message privé, sauf si un `threadId` explicite est fourni. +- La réutilisation de la même session pour un utilisateur cible en message privé ne s’active que lorsque les métadonnées de la session actuelle prouvent qu’il s’agit du même pair de message privé sur le même compte Matrix ; sinon OpenClaw revient au routage normal à portée utilisateur. +- Lorsque OpenClaw voit un salon de message privé Matrix entrer en collision avec un autre salon de message privé sur la même session partagée de message privé Matrix, il publie une seule fois un `m.notice` dans ce salon avec l’échappatoire `/focus` lorsque les associations de fils sont activées et l’indication `dm.sessionScope`. +- Les associations de fils à l’exécution sont prises en charge pour Matrix. `/focus`, `/unfocus`, `/agents`, `/session idle`, `/session max-age` et `/acp spawn` associé à un fil fonctionnent dans les salons et messages privés Matrix. +- Le `/focus` de niveau supérieur dans un salon/message privé Matrix crée un nouveau fil Matrix et l’associe à la session cible lorsque `threadBindings.spawnSubagentSessions=true`. +- Exécuter `/focus` ou `/acp spawn --thread here` à l’intérieur d’un fil Matrix existant associe ce fil actuel à la place. -## Liaisons de conversation ACP +## Associations de conversation ACP -Les salons Matrix, DM et fils Matrix existants peuvent être transformés en espaces de travail ACP durables sans changer la surface de chat. +Les salons, messages privés et fils Matrix existants peuvent être transformés en espaces de travail ACP durables sans changer la surface de chat. Flux opérateur rapide : -- Exécutez `/acp spawn codex --bind here` dans le DM Matrix, le salon ou le fil existant que vous voulez continuer à utiliser. -- Dans un DM Matrix ou salon de niveau supérieur, le DM/salon actuel reste la surface de chat et les messages futurs sont routés vers la session ACP créée. -- Dans un fil Matrix existant, `--bind here` lie ce fil actuel sur place. -- `/new` et `/reset` réinitialisent sur place cette même session ACP liée. -- `/acp close` ferme la session ACP et supprime la liaison. +- Exécutez `/acp spawn codex --bind here` dans le message privé Matrix, le salon ou le fil existant que vous voulez continuer à utiliser. +- Dans un message privé ou un salon Matrix de niveau supérieur, le message privé/salon actuel reste la surface de chat et les futurs messages sont routés vers la session ACP créée. +- À l’intérieur d’un fil Matrix existant, `--bind here` associe ce fil actuel sur place. +- `/new` et `/reset` réinitialisent sur place la même session ACP associée. +- `/acp close` ferme la session ACP et supprime l’association. Remarques : - `--bind here` ne crée pas de fil Matrix enfant. -- `threadBindings.spawnAcpSessions` n'est requis que pour `/acp spawn --thread auto|here`, lorsque OpenClaw doit créer ou lier un fil Matrix enfant. +- `threadBindings.spawnAcpSessions` n’est requis que pour `/acp spawn --thread auto|here`, lorsque OpenClaw doit créer ou associer un fil Matrix enfant. -### Configuration de liaison de fil +### Configuration des associations de fils -Matrix hérite des valeurs globales par défaut depuis `session.threadBindings`, et prend aussi en charge des surcharges par canal : +Matrix hérite des valeurs globales par défaut depuis `session.threadBindings` et prend aussi en charge des surcharges par canal : - `threadBindings.enabled` - `threadBindings.idleHours` @@ -731,35 +731,35 @@ Matrix hérite des valeurs globales par défaut depuis `session.threadBindings`, - `threadBindings.spawnSubagentSessions` - `threadBindings.spawnAcpSessions` -Les drapeaux de création liée à un fil Matrix sont activés sur demande : +Les indicateurs de création liés aux fils Matrix sont optionnels : -- Définissez `threadBindings.spawnSubagentSessions: true` pour permettre à `/focus` de niveau supérieur de créer et lier de nouveaux fils Matrix. -- Définissez `threadBindings.spawnAcpSessions: true` pour permettre à `/acp spawn --thread auto|here` de lier des sessions ACP à des fils Matrix. +- Définissez `threadBindings.spawnSubagentSessions: true` pour permettre à `/focus` de niveau supérieur de créer et d’associer de nouveaux fils Matrix. +- Définissez `threadBindings.spawnAcpSessions: true` pour permettre à `/acp spawn --thread auto|here` d’associer des sessions ACP à des fils Matrix. ## Réactions -Matrix prend en charge les actions de réaction sortantes, les notifications de réaction entrantes et les réactions d'accusé de réception entrantes. +Matrix prend en charge les actions de réaction sortantes, les notifications de réaction entrantes et les réactions d’accusé de réception entrantes. -- L'outillage de réaction sortante est contrôlé par `channels["matrix"].actions.reactions`. +- L’outillage de réaction sortante est contrôlé par `channels["matrix"].actions.reactions`. - `react` ajoute une réaction à un événement Matrix spécifique. - `reactions` liste le résumé actuel des réactions pour un événement Matrix spécifique. - `emoji=""` supprime les réactions propres au compte bot sur cet événement. -- `remove: true` supprime uniquement la réaction emoji spécifiée du compte bot. +- `remove: true` supprime uniquement la réaction avec l’emoji spécifié du compte bot. -La portée de la réaction d'accusé de réception est résolue dans cet ordre : +La portée des réactions d’accusé de réception se résout dans cet ordre : - `channels["matrix"].accounts..ackReaction` - `channels["matrix"].ackReaction` - `messages.ackReaction` -- repli sur l'emoji d'identité de l'agent +- repli sur l’emoji d’identité de l’agent -La portée des réactions d'accusé de réception est résolue dans cet ordre : +La portée de la réaction d’accusé de réception se résout dans cet ordre : - `channels["matrix"].accounts..ackReactionScope` - `channels["matrix"].ackReactionScope` - `messages.ackReactionScope` -Le mode de notification des réactions est résolu dans cet ordre : +Le mode de notification de réaction se résout dans cet ordre : - `channels["matrix"].accounts..reactionNotifications` - `channels["matrix"].reactionNotifications` @@ -767,30 +767,30 @@ Le mode de notification des réactions est résolu dans cet ordre : Comportement : -- `reactionNotifications: "own"` transfère les événements `m.reaction` ajoutés lorsqu'ils ciblent des messages Matrix rédigés par le bot. +- `reactionNotifications: "own"` transmet les événements `m.reaction` ajoutés lorsqu’ils ciblent des messages Matrix rédigés par le bot. - `reactionNotifications: "off"` désactive les événements système de réaction. -- Les suppressions de réaction ne sont pas synthétisées en événements système car Matrix les expose comme des redactions, et non comme des suppressions autonomes de `m.reaction`. +- Les suppressions de réaction ne sont pas synthétisées en événements système, car Matrix les expose comme des rédactions, pas comme des suppressions autonomes de `m.reaction`. -## Contexte d'historique +## Contexte d’historique -- `channels.matrix.historyLimit` contrôle combien de messages récents du salon sont inclus comme `InboundHistory` lorsqu'un message de salon Matrix déclenche l'agent. Revient à `messages.groupChat.historyLimit` ; si les deux ne sont pas définis, la valeur effective par défaut est `0`. Définissez `0` pour désactiver. -- L'historique de salon Matrix est limité au salon. Les DM continuent d'utiliser l'historique de session normal. -- L'historique de salon Matrix est limité aux messages en attente : OpenClaw met en tampon les messages de salon qui n'ont pas encore déclenché de réponse, puis prend un instantané de cette fenêtre lorsqu'une mention ou un autre déclencheur arrive. -- Le message déclencheur actuel n'est pas inclus dans `InboundHistory` ; il reste dans le corps entrant principal pour ce tour. -- Les nouvelles tentatives du même événement Matrix réutilisent l'instantané d'historique d'origine au lieu de dériver vers des messages de salon plus récents. +- `channels.matrix.historyLimit` contrôle combien de messages récents du salon sont inclus comme `InboundHistory` lorsqu’un message de salon Matrix déclenche l’agent. Revient à `messages.groupChat.historyLimit` ; si les deux ne sont pas définis, la valeur effective par défaut est `0`. Définissez `0` pour désactiver. +- L’historique des salons Matrix est limité au salon. Les messages privés continuent d’utiliser l’historique normal de session. +- L’historique des salons Matrix est limité aux messages en attente : OpenClaw met en mémoire tampon les messages du salon qui n’ont pas encore déclenché de réponse, puis capture cette fenêtre lorsqu’une mention ou un autre déclencheur arrive. +- Le message déclencheur actuel n’est pas inclus dans `InboundHistory` ; il reste dans le corps entrant principal pour ce tour. +- Les nouvelles tentatives du même événement Matrix réutilisent l’instantané d’historique d’origine au lieu de dériver vers des messages de salon plus récents. ## Visibilité du contexte -Matrix prend en charge le contrôle partagé `contextVisibility` pour le contexte de salon supplémentaire, tel que le texte de réponse récupéré, les racines de fils et l'historique en attente. +Matrix prend en charge le contrôle partagé `contextVisibility` pour le contexte de salon supplémentaire comme le texte de réponse récupéré, les racines de fil et l’historique en attente. - `contextVisibility: "all"` est la valeur par défaut. Le contexte supplémentaire est conservé tel que reçu. -- `contextVisibility: "allowlist"` filtre le contexte supplémentaire aux expéditeurs autorisés par les contrôles actifs de liste d'autorisation de salon/utilisateur. -- `contextVisibility: "allowlist_quote"` se comporte comme `allowlist`, mais conserve quand même une réponse citée explicite. +- `contextVisibility: "allowlist"` filtre le contexte supplémentaire vers les expéditeurs autorisés par les vérifications actives de liste d’autorisation de salon/utilisateur. +- `contextVisibility: "allowlist_quote"` se comporte comme `allowlist`, mais conserve tout de même une réponse citée explicite. Ce paramètre affecte la visibilité du contexte supplémentaire, pas la capacité du message entrant lui-même à déclencher une réponse. -L'autorisation de déclenchement continue de provenir de `groupPolicy`, `groups`, `groupAllowFrom` et des paramètres de politique DM. +L’autorisation du déclencheur provient toujours de `groupPolicy`, `groups`, `groupAllowFrom` et des paramètres de politique des messages privés. -## Politique DM et salon +## Politique de message privé et de salon ```json5 { @@ -813,28 +813,28 @@ L'autorisation de déclenchement continue de provenir de `groupPolicy`, `groups` } ``` -Voir [Groups](/fr/channels/groups) pour le filtrage par mention et le comportement des listes d'autorisation. +Voir [Groups](/fr/channels/groups) pour le comportement de filtrage par mention et de liste d’autorisation. -Exemple d'appairage pour les DM Matrix : +Exemple d’appairage pour les messages privés Matrix : ```bash openclaw pairing list matrix openclaw pairing approve matrix ``` -Si un utilisateur Matrix non approuvé continue de vous envoyer des messages avant l'approbation, OpenClaw réutilise le même code d'appairage en attente et peut renvoyer une réponse de rappel après un court délai au lieu d'en générer un nouveau. +Si un utilisateur Matrix non approuvé continue à vous envoyer des messages avant approbation, OpenClaw réutilise le même code d’appairage en attente et peut renvoyer une réponse de rappel après un court délai au lieu de créer un nouveau code. -Voir [Pairing](/fr/channels/pairing) pour le flux partagé d'appairage DM et la disposition de stockage. +Voir [Pairing](/fr/channels/pairing) pour le flux partagé d’appairage des messages privés et la disposition du stockage. ## Réparation directe de salon -Si l'état des messages directs n'est plus synchronisé, OpenClaw peut se retrouver avec des mappages `m.direct` obsolètes pointant vers d'anciens salons solo au lieu du DM actif. Inspectez le mappage actuel pour un pair avec : +Si l’état des messages directs se désynchronise, OpenClaw peut se retrouver avec des associations `m.direct` obsolètes qui pointent vers d’anciens salons solo au lieu du message privé actif. Inspectez l’association actuelle pour un pair avec : ```bash openclaw matrix direct inspect --user-id @alice:example.org ``` -Réparez-le avec : +Réparez-la avec : ```bash openclaw matrix direct repair --user-id @alice:example.org @@ -842,53 +842,53 @@ openclaw matrix direct repair --user-id @alice:example.org Le flux de réparation : -- privilégie un DM strict 1:1 déjà mappé dans `m.direct` -- revient à tout DM strict 1:1 actuellement rejoint avec cet utilisateur -- crée un nouveau salon direct et réécrit `m.direct` si aucun DM sain n'existe +- préfère un message privé strict 1:1 déjà associé dans `m.direct` +- retombe sur n’importe quel message privé strict 1:1 actuellement rejoint avec cet utilisateur +- crée un nouveau salon direct et réécrit `m.direct` si aucun message privé sain n’existe -Le flux de réparation ne supprime pas automatiquement les anciens salons. Il se contente de choisir le DM sain et de mettre à jour le mappage afin que les nouveaux envois Matrix, les avis de vérification et les autres flux de message direct ciblent à nouveau le bon salon. +Le flux de réparation ne supprime pas automatiquement les anciens salons. Il sélectionne seulement le message privé sain et met à jour l’association afin que les nouveaux envois Matrix, les avis de vérification et les autres flux de message direct ciblent de nouveau le bon salon. ## Approbations exec -Matrix peut agir comme client d'approbation natif pour un compte Matrix. Les contrôles natifs -de routage DM/canal restent sous la configuration des approbations exec : +Matrix peut agir comme client d’approbation natif pour un compte Matrix. Les réglages natifs +de routage des messages privés/canaux restent sous la configuration des approbations exec : - `channels.matrix.execApprovals.enabled` - `channels.matrix.execApprovals.approvers` (facultatif ; revient à `channels.matrix.dm.allowFrom`) -- `channels.matrix.execApprovals.target` (`dm` | `channel` | `both`, par défaut : `dm`) +- `channels.matrix.execApprovals.target` (`dm` | `channel` | `both`, défaut : `dm`) - `channels.matrix.execApprovals.agentFilter` - `channels.matrix.execApprovals.sessionFilter` -Les approbateurs doivent être des ID utilisateur Matrix tels que `@owner:example.org`. Matrix active automatiquement les approbations natives lorsque `enabled` est non défini ou vaut `"auto"` et qu'au moins un approbateur peut être résolu. Les approbations exec utilisent d'abord `execApprovals.approvers` et peuvent revenir à `channels.matrix.dm.allowFrom`. Les approbations de plugin autorisent via `channels.matrix.dm.allowFrom`. Définissez `enabled: false` pour désactiver explicitement Matrix comme client d'approbation natif. Les demandes d'approbation reviennent sinon à d'autres routes d'approbation configurées ou à la politique de repli des approbations. +Les approbateurs doivent être des ID utilisateur Matrix comme `@owner:example.org`. Matrix active automatiquement les approbations natives lorsque `enabled` n’est pas défini ou vaut `"auto"` et qu’au moins un approbateur peut être résolu. Les approbations exec utilisent d’abord `execApprovals.approvers` et peuvent revenir à `channels.matrix.dm.allowFrom`. Les approbations de Plugin sont autorisées via `channels.matrix.dm.allowFrom`. Définissez `enabled: false` pour désactiver explicitement Matrix comme client d’approbation natif. Sinon, les demandes d’approbation reviennent vers d’autres routes d’approbation configurées ou vers la politique de repli des approbations. -Le routage natif Matrix prend en charge les deux types d'approbation : +Le routage natif Matrix prend en charge les deux types d’approbation : -- `channels.matrix.execApprovals.*` contrôle le mode natif de diffusion DM/canal pour les invites d'approbation Matrix. -- Les approbations exec utilisent l'ensemble des approbateurs exec issu de `execApprovals.approvers` ou `channels.matrix.dm.allowFrom`. -- Les approbations de plugin utilisent la liste d'autorisation DM Matrix de `channels.matrix.dm.allowFrom`. -- Les raccourcis par réaction Matrix et les mises à jour de message s'appliquent aux approbations exec et plugin. +- `channels.matrix.execApprovals.*` contrôle le mode natif de diffusion vers message privé/canal pour les invites d’approbation Matrix. +- Les approbations exec utilisent l’ensemble d’approbateurs exec défini par `execApprovals.approvers` ou `channels.matrix.dm.allowFrom`. +- Les approbations de Plugin utilisent la liste d’autorisation des messages privés Matrix de `channels.matrix.dm.allowFrom`. +- Les raccourcis par réaction Matrix et les mises à jour de message s’appliquent aux approbations exec comme aux approbations de Plugin. Règles de livraison : -- `target: "dm"` envoie les invites d'approbation dans les DM des approbateurs -- `target: "channel"` renvoie l'invite dans le salon ou DM Matrix d'origine -- `target: "both"` envoie dans les DM des approbateurs et dans le salon ou DM Matrix d'origine +- `target: "dm"` envoie les invites d’approbation dans les messages privés des approbateurs +- `target: "channel"` renvoie l’invite dans le salon ou message privé Matrix d’origine +- `target: "both"` envoie vers les messages privés des approbateurs et vers le salon ou message privé Matrix d’origine -Les invites d'approbation Matrix ajoutent des raccourcis de réaction sur le message d'approbation principal : +Les invites d’approbation Matrix initialisent des raccourcis par réaction sur le message principal d’approbation : - `✅` = autoriser une fois - `❌` = refuser - `♾️` = toujours autoriser lorsque cette décision est permise par la politique exec effective -Les approbateurs peuvent réagir sur ce message ou utiliser les commandes slash de secours : `/approve allow-once`, `/approve allow-always`, ou `/approve deny`. +Les approbateurs peuvent réagir à ce message ou utiliser les commandes slash de repli : `/approve allow-once`, `/approve allow-always`, ou `/approve deny`. -Seuls les approbateurs résolus peuvent approuver ou refuser. Pour les approbations exec, la livraison dans le canal inclut le texte de la commande ; n'activez donc `channel` ou `both` que dans des salons de confiance. +Seuls les approbateurs résolus peuvent autoriser ou refuser. Pour les approbations exec, la livraison dans le canal inclut le texte de commande ; n’activez donc `channel` ou `both` que dans des salons de confiance. Surcharge par compte : - `channels.matrix.accounts..execApprovals` -Documentation liée : [Exec approvals](/fr/tools/exec-approvals) +Documentation connexe : [Exec approvals](/fr/tools/exec-approvals) ## Multi-comptes @@ -920,23 +920,24 @@ Documentation liée : [Exec approvals](/fr/tools/exec-approvals) } ``` -Les valeurs de niveau supérieur dans `channels.matrix` servent de valeurs par défaut pour les comptes nommés, sauf si un compte les remplace. -Vous pouvez limiter les entrées de salon héritées à un compte Matrix avec `groups..account`. +Les valeurs de niveau supérieur `channels.matrix` servent de valeurs par défaut pour les comptes nommés, sauf si un compte les remplace. +Vous pouvez limiter les entrées de salon héritées à un seul compte Matrix avec `groups..account`. Les entrées sans `account` restent partagées entre tous les comptes Matrix, et les entrées avec `account: "default"` continuent de fonctionner lorsque le compte par défaut est configuré directement au niveau supérieur dans `channels.matrix.*`. -Les valeurs d'authentification partagées partielles ne créent pas à elles seules un compte par défaut implicite distinct. OpenClaw ne synthétise le compte `default` de niveau supérieur que lorsque ce compte par défaut dispose d'une authentification fraîche (`homeserver` plus `accessToken`, ou `homeserver` plus `userId` et `password`) ; les comptes nommés peuvent tout de même rester détectables à partir de `homeserver` plus `userId` lorsque des identifiants mis en cache satisfont plus tard l'authentification. -Si Matrix possède déjà exactement un compte nommé, ou si `defaultAccount` pointe vers une clé de compte nommé existante, la promotion réparation/configuration initiale d'un compte unique vers multi-comptes préserve ce compte au lieu de créer une nouvelle entrée `accounts.default`. Seules les clés d'authentification/d'initialisation Matrix sont déplacées dans ce compte promu ; les clés partagées de politique de livraison restent au niveau supérieur. -Définissez `defaultAccount` lorsque vous voulez qu'OpenClaw privilégie un compte Matrix nommé pour le routage implicite, le probing et les opérations CLI. -Si vous configurez plusieurs comptes nommés, définissez `defaultAccount` ou passez `--account ` pour les commandes CLI qui dépendent de la sélection implicite du compte. -Passez `--account ` à `openclaw matrix verify ...` et `openclaw matrix devices ...` lorsque vous voulez remplacer cette sélection implicite pour une commande. +Les valeurs par défaut d’authentification partagées partielles ne créent pas à elles seules un compte par défaut implicite distinct. OpenClaw ne synthétise le compte `default` de niveau supérieur que lorsque ce compte par défaut dispose d’une authentification récente (`homeserver` plus `accessToken`, ou `homeserver` plus `userId` et `password`) ; les comptes nommés peuvent toujours rester détectables à partir de `homeserver` plus `userId` lorsque des identifiants mis en cache satisfont l’authentification plus tard. +Si Matrix a déjà exactement un compte nommé, ou si `defaultAccount` pointe vers une clé de compte nommé existante, la promotion réparation/configuration d’un seul compte vers plusieurs comptes préserve ce compte au lieu de créer une nouvelle entrée `accounts.default`. Seules les clés d’authentification/d’initialisation Matrix sont déplacées dans ce compte promu ; les clés de politique de livraison partagées restent au niveau supérieur. +Définissez `defaultAccount` lorsque vous voulez qu’OpenClaw privilégie un compte Matrix nommé pour le routage implicite, les sondes et les opérations CLI. +Si plusieurs comptes Matrix sont configurés et que l’un des ID de compte est `default`, OpenClaw utilise ce compte implicitement même si `defaultAccount` n’est pas défini. +Si vous configurez plusieurs comptes nommés, définissez `defaultAccount` ou passez `--account ` pour les commandes CLI qui reposent sur une sélection implicite du compte. +Passez `--account ` à `openclaw matrix verify ...` et `openclaw matrix devices ...` lorsque vous voulez remplacer cette sélection implicite pour une commande donnée. Voir [Référence de configuration](/fr/gateway/configuration-reference#multi-account-all-channels) pour le modèle multi-comptes partagé. ## Homeservers privés/LAN Par défaut, OpenClaw bloque les homeservers Matrix privés/internes pour la protection SSRF, sauf si vous -activez explicitement cette option compte par compte. +les autorisez explicitement compte par compte. -Si votre homeserver fonctionne sur localhost, une IP LAN/Tailscale ou un nom d'hôte interne, activez +Si votre homeserver fonctionne sur localhost, une IP LAN/Tailscale ou un nom d’hôte interne, activez `network.dangerouslyAllowPrivateNetwork` pour ce compte Matrix : ```json5 @@ -953,7 +954,7 @@ Si votre homeserver fonctionne sur localhost, une IP LAN/Tailscale ou un nom d'h } ``` -Exemple de configuration CLI : +Exemple de configuration via CLI : ```bash openclaw matrix account add \ @@ -963,10 +964,10 @@ openclaw matrix account add \ --access-token syt_ops_xxx ``` -Cette option d'adhésion explicite n'autorise que les cibles privées/internes de confiance. Les homeservers publics en clair tels que -`http://matrix.example.org:8008` restent bloqués. Préférez `https://` dès que possible. +Cette activation explicite n’autorise que les cibles privées/internes de confiance. Les homeservers publics en clair comme +`http://matrix.example.org:8008` restent bloqués. Préférez `https://` chaque fois que possible. -## Proxy du trafic Matrix +## Utiliser un proxy pour le trafic Matrix Si votre déploiement Matrix nécessite un proxy HTTP(S) sortant explicite, définissez `channels.matrix.proxy` : @@ -983,85 +984,85 @@ Si votre déploiement Matrix nécessite un proxy HTTP(S) sortant explicite, déf ``` Les comptes nommés peuvent remplacer la valeur par défaut de niveau supérieur avec `channels.matrix.accounts..proxy`. -OpenClaw utilise le même paramètre de proxy pour le trafic Matrix à l'exécution et pour les sondes d'état du compte. +OpenClaw utilise le même paramètre de proxy pour le trafic Matrix à l’exécution et pour les sondes d’état du compte. ## Résolution des cibles -Matrix accepte ces formes de cibles partout où OpenClaw vous demande une cible de salon ou d'utilisateur : +Matrix accepte ces formats de cible partout où OpenClaw vous demande une cible de salon ou d’utilisateur : -- Utilisateurs : `@user:server`, `user:@user:server`, ou `matrix:user:@user:server` -- Salons : `!room:server`, `room:!room:server`, ou `matrix:room:!room:server` -- Alias : `#alias:server`, `channel:#alias:server`, ou `matrix:channel:#alias:server` +- Utilisateurs : `@user:server`, `user:@user:server` ou `matrix:user:@user:server` +- Salons : `!room:server`, `room:!room:server` ou `matrix:room:!room:server` +- Alias : `#alias:server`, `channel:#alias:server` ou `matrix:channel:#alias:server` -La recherche en direct dans l'annuaire utilise le compte Matrix connecté : +La recherche en direct dans l’annuaire utilise le compte Matrix connecté : -- Les recherches d'utilisateur interrogent l'annuaire des utilisateurs Matrix sur ce homeserver. -- Les recherches de salon acceptent directement les ID et alias explicites de salon, puis reviennent à la recherche dans les noms des salons rejoints pour ce compte. -- La recherche par nom de salon rejoint fonctionne au mieux. Si un nom de salon ne peut pas être résolu en ID ou alias, il est ignoré lors de la résolution de la liste d'autorisation à l'exécution. +- Les recherches d’utilisateur interrogent l’annuaire des utilisateurs Matrix sur ce homeserver. +- Les recherches de salon acceptent directement les ID et alias de salon explicites, puis se replient sur la recherche dans les noms des salons rejoints pour ce compte. +- La recherche par nom de salon rejoint est effectuée au mieux. Si un nom de salon ne peut pas être résolu en ID ou alias, il est ignoré lors de la résolution de la liste d’autorisation à l’exécution. ## Référence de configuration - `enabled` : active ou désactive le canal. -- `name` : étiquette facultative pour le compte. +- `name` : libellé facultatif du compte. - `defaultAccount` : ID de compte préféré lorsque plusieurs comptes Matrix sont configurés. - `homeserver` : URL du homeserver, par exemple `https://matrix.example.org`. - `network.dangerouslyAllowPrivateNetwork` : autorise ce compte Matrix à se connecter à des homeservers privés/internes. Activez cette option lorsque le homeserver se résout vers `localhost`, une IP LAN/Tailscale ou un hôte interne tel que `matrix-synapse`. -- `proxy` : URL facultative du proxy HTTP(S) pour le trafic Matrix. Les comptes nommés peuvent remplacer la valeur par défaut de niveau supérieur avec leur propre `proxy`. +- `proxy` : URL facultative de proxy HTTP(S) pour le trafic Matrix. Les comptes nommés peuvent remplacer la valeur par défaut de niveau supérieur avec leur propre `proxy`. - `userId` : ID utilisateur Matrix complet, par exemple `@bot:example.org`. -- `accessToken` : jeton d'accès pour l'authentification par jeton. Les valeurs en clair et les valeurs SecretRef sont prises en charge pour `channels.matrix.accessToken` et `channels.matrix.accounts..accessToken` via les fournisseurs env/file/exec. Voir [Gestion des secrets](/fr/gateway/secrets). -- `password` : mot de passe pour la connexion par mot de passe. Les valeurs en clair et les valeurs SecretRef sont prises en charge. -- `deviceId` : ID explicite d'appareil Matrix. -- `deviceName` : nom d'affichage de l'appareil pour la connexion par mot de passe. -- `avatarUrl` : URL d'avatar personnel stockée pour la synchronisation du profil et les mises à jour `profile set`. -- `initialSyncLimit` : nombre maximal d'événements récupérés pendant la synchronisation au démarrage. -- `encryption` : active l'E2EE. -- `allowlistOnly` : lorsque `true`, transforme la politique de salon `open` en `allowlist`, et force toutes les politiques DM actives sauf `disabled` (y compris `pairing` et `open`) à `allowlist`. N'affecte pas les politiques `disabled`. -- `allowBots` : autorise les messages d'autres comptes Matrix OpenClaw configurés (`true` ou `"mentions"`). -- `groupPolicy` : `open`, `allowlist`, ou `disabled`. +- `accessToken` : jeton d’accès pour l’authentification basée sur un jeton. Les valeurs en texte brut et les valeurs SecretRef sont prises en charge pour `channels.matrix.accessToken` et `channels.matrix.accounts..accessToken` via les fournisseurs env/file/exec. Voir [Gestion des secrets](/fr/gateway/secrets). +- `password` : mot de passe pour la connexion basée sur un mot de passe. Les valeurs en texte brut et les valeurs SecretRef sont prises en charge. +- `deviceId` : ID explicite de l’appareil Matrix. +- `deviceName` : nom d’affichage de l’appareil pour la connexion par mot de passe. +- `avatarUrl` : URL d’avatar personnel stockée pour la synchronisation du profil et les mises à jour `profile set`. +- `initialSyncLimit` : nombre maximal d’événements récupérés pendant la synchronisation au démarrage. +- `encryption` : active le chiffrement de bout en bout. +- `allowlistOnly` : lorsque `true`, convertit la politique de salon `open` en `allowlist`, et force toutes les politiques de message privé actives sauf `disabled` (y compris `pairing` et `open`) à `allowlist`. N’affecte pas les politiques `disabled`. +- `allowBots` : autorise les messages provenant d’autres comptes Matrix OpenClaw configurés (`true` ou `"mentions"`). +- `groupPolicy` : `open`, `allowlist` ou `disabled`. - `contextVisibility` : mode de visibilité du contexte supplémentaire du salon (`all`, `allowlist`, `allowlist_quote`). -- `groupAllowFrom` : liste d'autorisation d'ID utilisateur pour le trafic de salon. Les entrées doivent être des ID utilisateur Matrix complets ; les noms non résolus sont ignorés à l'exécution. -- `historyLimit` : nombre maximal de messages de salon à inclure comme contexte d'historique de groupe. Revient à `messages.groupChat.historyLimit` ; si les deux ne sont pas définis, la valeur effective par défaut est `0`. Définissez `0` pour désactiver. -- `replyToMode` : `off`, `first`, `all`, ou `batched`. +- `groupAllowFrom` : liste d’autorisation des ID utilisateur pour le trafic de salon. Les entrées doivent être des ID utilisateur Matrix complets ; les noms non résolus sont ignorés à l’exécution. +- `historyLimit` : nombre maximal de messages de salon à inclure comme contexte d’historique de groupe. Revient à `messages.groupChat.historyLimit` ; si les deux ne sont pas définis, la valeur effective par défaut est `0`. Définissez `0` pour désactiver. +- `replyToMode` : `off`, `first`, `all` ou `batched`. - `markdown` : configuration facultative du rendu Markdown pour le texte Matrix sortant. -- `streaming` : `off` (par défaut), `"partial"`, `"quiet"`, `true`, ou `false`. `"partial"` et `true` activent des mises à jour de brouillon avec aperçu en premier via des messages texte Matrix normaux. `"quiet"` utilise des avis d'aperçu sans notification pour les configurations auto-hébergées avec règles push. `false` est équivalent à `"off"`. -- `blockStreaming` : `true` active des messages de progression séparés pour les blocs assistant terminés pendant que le streaming d'aperçu de brouillon est actif. -- `threadReplies` : `off`, `inbound`, ou `always`. -- `threadBindings` : surcharges par canal pour le routage et le cycle de vie des sessions liées aux fils. -- `startupVerification` : mode automatique de demande d'auto-vérification au démarrage (`if-unverified`, `off`). -- `startupVerificationCooldownHours` : délai avant une nouvelle tentative automatique de demande de vérification au démarrage. -- `textChunkLimit` : taille des segments de message sortant en caractères (s'applique lorsque `chunkMode` vaut `length`). -- `chunkMode` : `length` découpe les messages par nombre de caractères ; `newline` les découpe aux limites de ligne. -- `responsePrefix` : chaîne facultative préfixée à toutes les réponses sortantes de ce canal. -- `ackReaction` : surcharge facultative de réaction d'accusé de réception pour ce canal/compte. -- `ackReactionScope` : surcharge facultative de la portée de la réaction d'accusé de réception (`group-mentions`, `group-all`, `direct`, `all`, `none`, `off`). -- `reactionNotifications` : mode de notification des réactions entrantes (`own`, `off`). +- `streaming` : `off` (par défaut), `"partial"`, `"quiet"`, `true` ou `false`. `"partial"` et `true` activent les mises à jour de brouillon avec aperçu initial via des messages texte Matrix normaux. `"quiet"` utilise des avis d’aperçu sans notification pour les configurations auto-hébergées avec règles push. `false` est équivalent à `"off"`. +- `blockStreaming` : `true` active des messages de progression séparés pour les blocs d’assistant terminés pendant que le streaming d’aperçu de brouillon est actif. +- `threadReplies` : `off`, `inbound` ou `always`. +- `threadBindings` : surcharges par canal pour le routage et le cycle de vie des sessions associées à un fil. +- `startupVerification` : mode automatique de demande d’auto-vérification au démarrage (`if-unverified`, `off`). +- `startupVerificationCooldownHours` : délai d’attente avant de réessayer les demandes automatiques de vérification au démarrage. +- `textChunkLimit` : taille des segments de message sortant en caractères (s’applique lorsque `chunkMode` est `length`). +- `chunkMode` : `length` découpe les messages par nombre de caractères ; `newline` découpe aux limites de ligne. +- `responsePrefix` : chaîne facultative ajoutée au début de toutes les réponses sortantes pour ce canal. +- `ackReaction` : surcharge facultative de réaction d’accusé de réception pour ce canal/compte. +- `ackReactionScope` : surcharge facultative de portée de réaction d’accusé de réception (`group-mentions`, `group-all`, `direct`, `all`, `none`, `off`). +- `reactionNotifications` : mode de notification de réaction entrante (`own`, `off`). - `mediaMaxMb` : limite de taille des médias en Mo pour les envois sortants et le traitement des médias entrants. -- `autoJoin` : politique de jonction automatique sur invitation (`always`, `allowlist`, `off`). Par défaut : `off`. S'applique à toutes les invitations Matrix, y compris les invitations de type DM. -- `autoJoinAllowlist` : salons/alias autorisés lorsque `autoJoin` vaut `allowlist`. Les entrées d'alias sont résolues vers des ID de salon pendant le traitement de l'invitation ; OpenClaw ne fait pas confiance à l'état d'alias revendiqué par le salon invité. -- `dm` : bloc de politique DM (`enabled`, `policy`, `allowFrom`, `sessionScope`, `threadReplies`). -- `dm.policy` : contrôle l'accès DM après qu'OpenClaw a rejoint le salon et l'a classé comme DM. Cela ne change pas le fait qu'une invitation soit rejointe automatiquement ou non. -- `dm.allowFrom` : les entrées doivent être des ID utilisateur Matrix complets, sauf si vous les avez déjà résolus via une recherche en direct dans l'annuaire. -- `dm.sessionScope` : `per-user` (par défaut) ou `per-room`. Utilisez `per-room` si vous voulez que chaque salon DM Matrix conserve un contexte séparé même si le pair est le même. -- `dm.threadReplies` : surcharge de politique de fil pour DM uniquement (`off`, `inbound`, `always`). Elle remplace le paramètre `threadReplies` de niveau supérieur pour le placement des réponses et l'isolation des sessions dans les DM. -- `execApprovals` : livraison native Matrix des approbations exec (`enabled`, `approvers`, `target`, `agentFilter`, `sessionFilter`). +- `autoJoin` : politique de jonction automatique sur invitation (`always`, `allowlist`, `off`). Par défaut : `off`. S’applique à toutes les invitations Matrix, y compris les invitations de type message privé. +- `autoJoinAllowlist` : salons/alias autorisés lorsque `autoJoin` est `allowlist`. Les entrées d’alias sont résolues en ID de salon lors du traitement de l’invitation ; OpenClaw ne se fie pas à l’état d’alias revendiqué par le salon invité. +- `dm` : bloc de politique des messages privés (`enabled`, `policy`, `allowFrom`, `sessionScope`, `threadReplies`). +- `dm.policy` : contrôle l’accès aux messages privés après qu’OpenClaw a rejoint le salon et l’a classé comme message privé. Cela ne change pas si une invitation est rejointe automatiquement. +- `dm.allowFrom` : les entrées doivent être des ID utilisateur Matrix complets, sauf si vous les avez déjà résolues via la recherche en direct dans l’annuaire. +- `dm.sessionScope` : `per-user` (par défaut) ou `per-room`. Utilisez `per-room` lorsque vous voulez que chaque salon de message privé Matrix conserve un contexte distinct même si le pair est le même. +- `dm.threadReplies` : surcharge de politique de fil pour les messages privés uniquement (`off`, `inbound`, `always`). Elle remplace le paramètre `threadReplies` de niveau supérieur à la fois pour le placement des réponses et pour l’isolation de session dans les messages privés. +- `execApprovals` : livraison native des approbations exec Matrix (`enabled`, `approvers`, `target`, `agentFilter`, `sessionFilter`). - `execApprovals.approvers` : ID utilisateur Matrix autorisés à approuver les demandes exec. Facultatif lorsque `dm.allowFrom` identifie déjà les approbateurs. - `execApprovals.target` : `dm | channel | both` (par défaut : `dm`). -- `accounts` : surcharges nommées par compte. Les valeurs de niveau supérieur dans `channels.matrix` servent de valeurs par défaut pour ces entrées. -- `groups` : mappage de politique par salon. Préférez les ID ou alias de salon ; les noms de salon non résolus sont ignorés à l'exécution. L'identité de session/groupe utilise l'ID stable du salon après résolution. -- `groups..account` : limite une entrée de salon héritée à un compte Matrix spécifique dans les configurations multi-comptes. -- `groups..allowBots` : surcharge au niveau du salon pour les expéditeurs configurés comme bots (`true` ou `"mentions"`). -- `groups..users` : liste d'autorisation d'expéditeur par salon. -- `groups..tools` : surcharges d'autorisation/interdiction des outils par salon. -- `groups..autoReply` : surcharge au niveau du salon du filtrage par mention. `true` désactive les exigences de mention pour ce salon ; `false` les réactive de force. +- `accounts` : surcharges nommées par compte. Les valeurs `channels.matrix` de niveau supérieur servent de valeurs par défaut pour ces entrées. +- `groups` : mappage de politique par salon. Préférez les ID ou alias de salon ; les noms de salon non résolus sont ignorés à l’exécution. L’identité de session/groupe utilise l’ID de salon stable après résolution. +- `groups..account` : restreint une entrée de salon héritée à un compte Matrix spécifique dans les configurations multi-comptes. +- `groups..allowBots` : surcharge au niveau du salon pour les expéditeurs de bots configurés (`true` ou `"mentions"`). +- `groups..users` : liste d’autorisation des expéditeurs par salon. +- `groups..tools` : surcharges d’autorisation/interdiction d’outils par salon. +- `groups..autoReply` : surcharge de filtrage par mention au niveau du salon. `true` désactive les exigences de mention pour ce salon ; `false` les réactive de force. - `groups..skills` : filtre facultatif de Skills au niveau du salon. - `groups..systemPrompt` : extrait facultatif de prompt système au niveau du salon. - `rooms` : alias hérité pour `groups`. -- `actions` : contrôle par action des outils (`messages`, `reactions`, `pins`, `profile`, `memberInfo`, `channelInfo`, `verification`). +- `actions` : contrôle d’accès par action pour les outils (`messages`, `reactions`, `pins`, `profile`, `memberInfo`, `channelInfo`, `verification`). -## Lié +## Liens connexes -- [Présentation des canaux](/fr/channels) — tous les canaux pris en charge -- [Pairing](/fr/channels/pairing) — authentification DM et flux d'appairage -- [Groups](/fr/channels/groups) — comportement des discussions de groupe et filtrage par mention +- [Vue d’ensemble des canaux](/fr/channels) — tous les canaux pris en charge +- [Appairage](/fr/channels/pairing) — authentification des messages privés et flux d’appairage +- [Groups](/fr/channels/groups) — comportement du chat de groupe et filtrage par mention - [Routage des canaux](/fr/channels/channel-routing) — routage de session pour les messages -- [Sécurité](/fr/gateway/security) — modèle d'accès et durcissement +- [Sécurité](/fr/gateway/security) — modèle d’accès et durcissement diff --git a/docs/fr/concepts/dreaming.md b/docs/fr/concepts/dreaming.md index 18836723b..6aebd330d 100644 --- a/docs/fr/concepts/dreaming.md +++ b/docs/fr/concepts/dreaming.md @@ -1,15 +1,15 @@ --- read_when: - - Vous voulez que la promotion de la mémoire s'exécute automatiquement - - Vous voulez comprendre à quoi sert chaque phase de Dreaming - - Vous voulez ajuster la consolidation sans polluer MEMORY.md -summary: Consolidation de la mémoire en arrière-plan avec phases légère, profonde et REM, plus un Journal des rêves + - Vous souhaitez que la promotion de la mémoire s’exécute automatiquement + - Vous voulez comprendre ce que fait chaque phase de Dreaming + - Vous voulez ajuster la consolidation sans polluer `MEMORY.md` +summary: Consolidation de la mémoire en arrière-plan avec des phases légères, profondes et REM, plus un journal de rêves title: Dreaming (expérimental) x-i18n: - generated_at: "2026-04-09T01:27:47Z" + generated_at: "2026-04-15T06:56:37Z" model: gpt-5.4 provider: openai - source_hash: 26476eddb8260e1554098a6adbb069cf7f5e284cf2e09479c6d9d8f8b93280ef + source_hash: 5882a5068f2eabe54ca9893184e5385330a432b921870c38626399ce11c31e25 source_path: concepts/dreaming.md workflow: 15 --- @@ -17,8 +17,8 @@ x-i18n: # Dreaming (expérimental) Dreaming est le système de consolidation de la mémoire en arrière-plan dans `memory-core`. -Il aide OpenClaw à déplacer des signaux forts de court terme vers une mémoire durable, tout en -gardant le processus explicable et vérifiable. +Il aide OpenClaw à déplacer les signaux forts à court terme vers une mémoire durable tout en +gardant le processus explicable et révisable. Dreaming est **optionnel** et désactivé par défaut. @@ -26,107 +26,111 @@ Dreaming est **optionnel** et désactivé par défaut. Dreaming conserve deux types de sortie : -- **État machine** dans `memory/.dreams/` (magasin de rappel, signaux de phase, points de contrôle d'ingestion, verrous). -- **Sortie lisible par les humains** dans `DREAMS.md` (ou `dreams.md` existant) et fichiers de rapport de phase facultatifs sous `memory/dreaming//YYYY-MM-DD.md`. +- **État machine** dans `memory/.dreams/` (magasin de rappel, signaux de phase, points de contrôle d’ingestion, verrous). +- **Sortie lisible par des humains** dans `DREAMS.md` (ou `dreams.md` existant) et des fichiers de rapport de phase facultatifs sous `memory/dreaming//YYYY-MM-DD.md`. -La promotion à long terme n'écrit toujours que dans `MEMORY.md`. +La promotion à long terme continue d’écrire uniquement dans `MEMORY.md`. ## Modèle de phase Dreaming utilise trois phases coopératives : -| Phase | Objectif | Écriture durable | -| ----- | -------- | ---------------- | -| Light | Trier et préparer le matériel récent de court terme | Non | -| Deep | Évaluer et promouvoir les candidats durables | Oui (`MEMORY.md`) | -| REM | Réfléchir aux thèmes et aux idées récurrentes | Non | +| Phase | Objectif | Écriture durable | +| ----- | ----------------------------------------- | ----------------- | +| Light | Trier et préparer le matériel récent à court terme | Non | +| Deep | Évaluer et promouvoir les candidats durables | Oui (`MEMORY.md`) | +| REM | Réfléchir aux thèmes et aux idées récurrentes | Non | -Ces phases sont des détails d'implémentation internes, pas des « modes » -distincts configurés par l'utilisateur. +Ces phases sont des détails d’implémentation internes, et non des « modes » +distincts configurés par l’utilisateur. ### Phase Light -La phase Light ingère les signaux récents de mémoire quotidienne et les traces de rappel, les déduplique -et prépare des lignes candidates. +La phase Light ingère les signaux récents de mémoire quotidienne et les traces de rappel, les déduplique, +et prépare les lignes candidates. -- Lit l'état de rappel à court terme, les fichiers récents de mémoire quotidienne et les transcriptions de session expurgées lorsqu'elles sont disponibles. -- Écrit un bloc `## Light Sleep` géré lorsque le stockage inclut une sortie inline. +- Lit l’état de rappel à court terme, les fichiers récents de mémoire quotidienne et les transcriptions de session expurgées lorsqu’elles sont disponibles. +- Écrit un bloc géré `## Light Sleep` lorsque le stockage inclut une sortie en ligne. - Enregistre des signaux de renforcement pour le classement Deep ultérieur. -- N'écrit jamais dans `MEMORY.md`. +- N’écrit jamais dans `MEMORY.md`. ### Phase Deep La phase Deep décide de ce qui devient une mémoire à long terme. -- Classe les candidats à l'aide d'un score pondéré et de seuils de validation. +- Classe les candidats à l’aide d’un score pondéré et de seuils de validation. - Exige que `minScore`, `minRecallCount` et `minUniqueQueries` soient atteints. -- Réhydrate les extraits depuis les fichiers quotidiens actifs avant l'écriture, afin que les extraits obsolètes ou supprimés soient ignorés. +- Réhydrate les extraits à partir des fichiers quotidiens actifs avant l’écriture, de sorte que les extraits obsolètes ou supprimés soient ignorés. - Ajoute les entrées promues à `MEMORY.md`. -- Écrit un résumé `## Deep Sleep` dans `DREAMS.md` et écrit éventuellement `memory/dreaming/deep/YYYY-MM-DD.md`. +- Écrit un résumé `## Deep Sleep` dans `DREAMS.md` et peut aussi écrire `memory/dreaming/deep/YYYY-MM-DD.md`. ### Phase REM La phase REM extrait des motifs et des signaux réflexifs. -- Construit des résumés de thèmes et de réflexions à partir des traces récentes de court terme. -- Écrit un bloc `## REM Sleep` géré lorsque le stockage inclut une sortie inline. +- Construit des résumés de thèmes et de réflexions à partir des traces récentes à court terme. +- Écrit un bloc géré `## REM Sleep` lorsque le stockage inclut une sortie en ligne. - Enregistre des signaux de renforcement REM utilisés par le classement Deep. -- N'écrit jamais dans `MEMORY.md`. +- N’écrit jamais dans `MEMORY.md`. ## Ingestion des transcriptions de session Dreaming peut ingérer des transcriptions de session expurgées dans le corpus de Dreaming. Lorsque -des transcriptions sont disponibles, elles sont intégrées à la phase Light avec les signaux -de mémoire quotidienne et les traces de rappel. Le contenu personnel et sensible est expurgé -avant l'ingestion. +des transcriptions sont disponibles, elles sont intégrées à la phase Light en plus des signaux de +mémoire quotidienne et des traces de rappel. Le contenu personnel et sensible est expurgé +avant l’ingestion. ## Journal des rêves -Dreaming conserve également un **Journal des rêves** narratif dans `DREAMS.md`. -Une fois que chaque phase dispose de suffisamment de matière, `memory-core` exécute un tour -de sous-agent en arrière-plan avec effort optimal (en utilisant le modèle d'exécution par défaut) et ajoute une courte entrée au journal. +Dreaming conserve aussi un **journal des rêves** narratif dans `DREAMS.md`. +Après que chaque phase a accumulé suffisamment de matière, `memory-core` exécute un tour +de sous-agent en arrière-plan en mode best-effort (en utilisant le modèle d’exécution par défaut) +et ajoute une courte entrée au journal. -Ce journal est destiné à la lecture humaine dans l'interface Dreams, pas à servir de source de promotion. +Ce journal est destiné à la lecture humaine dans l’interface Dreams, et non à servir de source de promotion. +Les artefacts de journal/rapport générés par Dreaming sont exclus de la +promotion à court terme. Seuls les extraits de mémoire ancrés dans les faits peuvent être promus dans +`MEMORY.md`. -Il existe également une voie de remplissage historique fondée pour le travail de révision et de récupération : +Il existe aussi un circuit de remplissage historique ancré dans les faits pour les travaux de révision et de récupération : -- `memory rem-harness --path ... --grounded` prévisualise une sortie de journal fondée à partir de notes historiques `YYYY-MM-DD.md`. -- `memory rem-backfill --path ...` écrit des entrées de journal fondées réversibles dans `DREAMS.md`. -- `memory rem-backfill --path ... --stage-short-term` prépare des candidats durables fondés dans le même magasin de preuves à court terme que la phase Deep normale utilise déjà. -- `memory rem-backfill --rollback` et `--rollback-short-term` suppriment ces artefacts de remplissage préparés sans toucher aux entrées ordinaires du journal ni au rappel actif normal à court terme. +- `memory rem-harness --path ... --grounded` prévisualise la sortie du journal ancré dans les faits à partir des notes historiques `YYYY-MM-DD.md`. +- `memory rem-backfill --path ...` écrit des entrées réversibles de journal ancré dans les faits dans `DREAMS.md`. +- `memory rem-backfill --path ... --stage-short-term` prépare des candidats durables ancrés dans les faits dans le même magasin de preuves à court terme que la phase Deep normale utilise déjà. +- `memory rem-backfill --rollback` et `--rollback-short-term` suppriment ces artefacts de remplissage préparés sans toucher aux entrées ordinaires du journal ni au rappel actif à court terme. -L'interface Control UI expose le même flux de remplissage/réinitialisation du journal afin que vous puissiez inspecter -les résultats dans la scène Dreams avant de décider si les candidats fondés -méritent une promotion. La scène affiche également une voie fondée distincte afin que vous puissiez voir -quelles entrées préparées à court terme proviennent d'une relecture historique, quels éléments promus -ont été guidés par le mode fondé, et effacer uniquement les entrées préparées fondées sans -toucher à l'état ordinaire actif de court terme. +L’interface Control expose le même flux de remplissage/réinitialisation du journal afin que vous puissiez inspecter +les résultats dans la scène Dreams avant de décider si les candidats ancrés dans les faits +méritent une promotion. La scène affiche aussi une voie ancrée distincte pour que vous puissiez voir +quelles entrées préparées à court terme proviennent d’une relecture historique, quels éléments promus +ont été guidés par des données ancrées dans les faits, et effacer uniquement les entrées préparées ancrées +sans toucher à l’état ordinaire actif à court terme. ## Signaux de classement Deep Le classement Deep utilise six signaux de base pondérés plus le renforcement de phase : -| Signal | Poids | Description | -| ------------------- | ------ | ------------------------------------------------- | -| Fréquence | 0.24 | Nombre de signaux de court terme accumulés par l'entrée | -| Pertinence | 0.30 | Qualité moyenne de récupération pour l'entrée | -| Diversité des requêtes | 0.15 | Contextes distincts de requête/jour qui l'ont fait émerger | -| Récence | 0.15 | Score de fraîcheur atténué dans le temps | -| Consolidation | 0.10 | Force de récurrence sur plusieurs jours | -| Richesse conceptuelle | 0.06 | Densité des balises de concept depuis l'extrait/le chemin | +| Signal | Poids | Description | +| ------------------- | ----- | ------------------------------------------------- | +| Fréquence | 0.24 | Nombre de signaux à court terme accumulés par l’entrée | +| Pertinence | 0.30 | Qualité moyenne de récupération pour l’entrée | +| Diversité des requêtes | 0.15 | Contextes distincts de requête/jour qui l’ont fait apparaître | +| Récence | 0.15 | Score de fraîcheur décroissant avec le temps | +| Consolidation | 0.10 | Force de récurrence sur plusieurs jours | +| Richesse conceptuelle | 0.06 | Densité des balises de concept à partir de l’extrait/du chemin | -Les occurrences des phases Light et REM ajoutent un petit bonus atténué par la récence depuis +Les occurrences des phases Light et REM ajoutent un petit bonus décroissant avec le temps à partir de `memory/.dreams/phase-signals.json`. ## Planification -Lorsqu'il est activé, `memory-core` gère automatiquement une tâche cron pour un balayage -complet de Dreaming. Chaque balayage exécute les phases dans l'ordre : light -> REM -> deep. +Lorsqu’il est activé, `memory-core` gère automatiquement une tâche Cron pour un cycle complet +de Dreaming. Chaque cycle exécute les phases dans l’ordre : light -> REM -> deep. Comportement de cadence par défaut : -| Paramètre | Par défaut | -| -------------------- | ----------- | +| Paramètre | Par défaut | +| -------------------- | ---------- | | `dreaming.frequency` | `0 3 * * *` | ## Démarrage rapide @@ -149,7 +153,7 @@ Activer Dreaming : } ``` -Activer Dreaming avec une cadence de balayage personnalisée : +Activer Dreaming avec une cadence de cycle personnalisée : ```json { @@ -189,8 +193,8 @@ openclaw memory promote --limit 5 openclaw memory status --deep ``` -La commande manuelle `memory promote` utilise par défaut les seuils de la phase Deep, sauf remplacement -par des drapeaux CLI. +La commande manuelle `memory promote` utilise par défaut les seuils de la phase Deep, sauf en cas de remplacement +par des indicateurs CLI. Expliquer pourquoi un candidat spécifique serait ou ne serait pas promu : @@ -211,31 +215,31 @@ openclaw memory rem-harness --json Tous les paramètres se trouvent sous `plugins.entries.memory-core.config.dreaming`. -| Clé | Par défaut | -| ----------- | ----------- | -| `enabled` | `false` | +| Clé | Par défaut | +| ----------- | ---------- | +| `enabled` | `false` | | `frequency` | `0 3 * * *` | -La politique de phase, les seuils et le comportement de stockage sont des détails -d'implémentation internes (pas une configuration destinée à l'utilisateur). +La politique des phases, les seuils et le comportement de stockage sont des détails +d’implémentation internes (et non une configuration destinée aux utilisateurs). -Consultez la [référence de configuration de la mémoire](/fr/reference/memory-config#dreaming-experimental) +Voir la [référence de configuration Memory](/fr/reference/memory-config#dreaming-experimental) pour la liste complète des clés. ## Interface Dreams -Lorsqu'il est activé, l'onglet **Dreams** de la passerelle affiche : +Lorsqu’il est activé, l’onglet **Dreams** du Gateway affiche : -- l'état actuel d'activation de Dreaming -- l'état au niveau des phases et la présence du balayage géré -- les comptes de court terme, fondés, de signaux et des promotions du jour -- l'heure de la prochaine exécution planifiée -- une voie de scène fondée distincte pour les entrées préparées issues de la relecture historique -- un lecteur de Journal des rêves extensible alimenté par `doctor.memory.dreamDiary` +- l’état actuel d’activation de Dreaming +- le statut au niveau des phases et la présence d’un cycle géré +- les nombres d’éléments à court terme, ancrés dans les faits, de signaux et promus aujourd’hui +- l’heure de la prochaine exécution planifiée +- une voie ancrée distincte dans la scène pour les entrées préparées issues d’une relecture historique +- un lecteur de journal des rêves extensible alimenté par `doctor.memory.dreamDiary` ## Lié -- [Mémoire](/fr/concepts/memory) -- [Recherche dans la mémoire](/fr/concepts/memory-search) +- [Memory](/fr/concepts/memory) +- [Recherche Memory](/fr/concepts/memory-search) - [CLI memory](/cli/memory) -- [Référence de configuration de la mémoire](/fr/reference/memory-config) +- [Référence de configuration Memory](/fr/reference/memory-config) diff --git a/docs/fr/gateway/local-models.md b/docs/fr/gateway/local-models.md index 72a566571..819678d28 100644 --- a/docs/fr/gateway/local-models.md +++ b/docs/fr/gateway/local-models.md @@ -1,28 +1,28 @@ --- read_when: - - Vous souhaitez servir des modèles depuis votre propre machine GPU. - - Vous configurez LM Studio ou un proxy compatible OpenAI. - - Vous avez besoin des conseils les plus sûrs pour les modèles locaux. -summary: Exécutez OpenClaw sur des LLM locaux (LM Studio, vLLM, LiteLLM, points de terminaison OpenAI personnalisés) + - Vous voulez servir des modèles depuis votre propre machine GPU + - Vous configurez LM Studio ou un proxy compatible OpenAI + - Vous avez besoin des conseils les plus sûrs pour les modèles locaux +summary: Exécuter OpenClaw sur des LLM locaux (LM Studio, vLLM, LiteLLM, points de terminaison OpenAI personnalisés) title: Modèles locaux x-i18n: - generated_at: "2026-04-14T06:55:40Z" + generated_at: "2026-04-15T06:56:33Z" model: gpt-5.4 provider: openai - source_hash: 1544c522357ba4b18dfa6d05ea8d60c7c6262281b53863d9aee7002464703ca7 + source_hash: 8778cc1c623a356ff3cf306c494c046887f9417a70ec71e659e4a8aae912a780 source_path: gateway/local-models.md workflow: 15 --- # Modèles locaux -Le local est possible, mais OpenClaw s’attend à un contexte large ainsi qu’à de solides défenses contre l’injection de prompt. Les petites cartes tronquent le contexte et affaiblissent la sécurité. Visez haut : **≥2 Mac Studios au maximum de leur capacité ou une machine GPU équivalente (~30 k$+)**. Un seul GPU de **24 Go** ne fonctionne que pour des prompts plus légers avec une latence plus élevée. Utilisez la **variante de modèle la plus grande / de taille complète que vous pouvez exécuter** ; les checkpoints fortement quantifiés ou « small » augmentent le risque d’injection de prompt (voir [Sécurité](/fr/gateway/security)). +Le local est possible, mais OpenClaw attend une grande fenêtre de contexte ainsi que de solides défenses contre l’injection de prompt. Les petites cartes tronquent le contexte et affaiblissent la sécurité. Visez haut : **≥2 Mac Studio au maximum ou une machine GPU équivalente (~30 k$+)**. Un seul GPU de **24 Go** ne fonctionne que pour des prompts plus légers, avec une latence plus élevée. Utilisez la **variante de modèle la plus grande / pleine taille que vous puissiez exécuter** ; les checkpoints fortement quantifiés ou « petits » augmentent le risque d’injection de prompt (voir [Sécurité](/fr/gateway/security)). -Si vous voulez la configuration locale la plus simple, commencez par [LM Studio](/fr/providers/lmstudio) ou [Ollama](/fr/providers/ollama) et `openclaw onboard`. Cette page est le guide orienté recommandations pour les piles locales plus haut de gamme et les serveurs locaux personnalisés compatibles OpenAI. +Si vous voulez la configuration locale la plus simple, commencez par [LM Studio](/fr/providers/lmstudio) ou [Ollama](/fr/providers/ollama) et `openclaw onboard`. Cette page est le guide prescriptif pour les piles locales plus haut de gamme et les serveurs locaux personnalisés compatibles OpenAI. ## Recommandé : LM Studio + grand modèle local (API Responses) -La meilleure pile locale actuelle. Chargez un grand modèle dans LM Studio (par exemple, une version taille complète de Qwen, DeepSeek ou Llama), activez le serveur local (par défaut `http://127.0.0.1:1234`), et utilisez l’API Responses pour séparer le raisonnement du texte final. +La meilleure pile locale actuelle. Chargez un grand modèle dans LM Studio (par exemple, une version pleine taille de Qwen, DeepSeek ou Llama), activez le serveur local (par défaut `http://127.0.0.1:1234`), et utilisez l’API Responses pour séparer le raisonnement du texte final. ```json5 { @@ -59,16 +59,16 @@ La meilleure pile locale actuelle. Chargez un grand modèle dans LM Studio (par } ``` -**Liste de configuration** +**Liste de vérification de configuration** - Installez LM Studio : [https://lmstudio.ai](https://lmstudio.ai) -- Dans LM Studio, téléchargez la **plus grande version de modèle disponible** (évitez les variantes « small » / fortement quantifiées), démarrez le serveur, et confirmez que `http://127.0.0.1:1234/v1/models` le liste. +- Dans LM Studio, téléchargez la **plus grande version de modèle disponible** (évitez les variantes « small » / fortement quantifiées), démarrez le serveur et confirmez que `http://127.0.0.1:1234/v1/models` le liste. - Remplacez `my-local-model` par l’ID réel du modèle affiché dans LM Studio. - Gardez le modèle chargé ; le chargement à froid ajoute de la latence au démarrage. - Ajustez `contextWindow` / `maxTokens` si votre version de LM Studio diffère. - Pour WhatsApp, restez sur l’API Responses afin que seul le texte final soit envoyé. -Gardez les modèles hébergés configurés même lorsque vous exécutez du local ; utilisez `models.mode: "merge"` pour que des solutions de repli restent disponibles. +Conservez aussi des modèles hébergés configurés même lorsque vous exécutez en local ; utilisez `models.mode: "merge"` pour garder des solutions de repli disponibles. ### Configuration hybride : primaire hébergé, repli local @@ -113,16 +113,16 @@ Gardez les modèles hébergés configurés même lorsque vous exécutez du local ### Priorité au local avec filet de sécurité hébergé -Inversez l’ordre du primaire et du repli ; conservez le même bloc `providers` et `models.mode: "merge"` afin de pouvoir basculer vers Sonnet ou Opus lorsque la machine locale est indisponible. +Inversez l’ordre du primaire et des fallbacks ; conservez le même bloc `providers` et `models.mode: "merge"` afin de pouvoir revenir sur Sonnet ou Opus lorsque la machine locale est indisponible. ### Hébergement régional / routage des données -- Des variantes MiniMax/Kimi/GLM hébergées existent aussi sur OpenRouter avec des points de terminaison épinglés par région (par ex. hébergés aux États-Unis). Choisissez la variante régionale correspondante pour garder le trafic dans la juridiction de votre choix tout en utilisant `models.mode: "merge"` pour les replis Anthropic/OpenAI. -- Le tout-local reste la voie la plus forte pour la confidentialité ; le routage régional hébergé constitue un compromis lorsque vous avez besoin de fonctionnalités de fournisseur tout en voulant garder le contrôle sur le flux de données. +- Des variantes MiniMax/Kimi/GLM hébergées existent aussi sur OpenRouter avec des points de terminaison épinglés par région (par exemple, hébergés aux États-Unis). Choisissez-y la variante régionale pour conserver le trafic dans la juridiction de votre choix tout en utilisant `models.mode: "merge"` pour les fallbacks Anthropic/OpenAI. +- Le tout-local reste la meilleure option pour la confidentialité ; le routage régional hébergé est l’entre-deux lorsque vous avez besoin de fonctionnalités fournisseur tout en gardant le contrôle du flux de données. ## Autres proxys locaux compatibles OpenAI -vLLM, LiteLLM, OAI-proxy ou des passerelles personnalisées fonctionnent s’ils exposent un point de terminaison `/v1` de style OpenAI. Remplacez le bloc provider ci-dessus par votre point de terminaison et l’ID de votre modèle : +vLLM, LiteLLM, OAI-proxy ou des Gateway personnalisés fonctionnent s’ils exposent un point de terminaison `/v1` de style OpenAI. Remplacez le bloc fournisseur ci-dessus par votre point de terminaison et l’ID de modèle : ```json5 { @@ -150,42 +150,30 @@ vLLM, LiteLLM, OAI-proxy ou des passerelles personnalisées fonctionnent s’ils } ``` -Conservez `models.mode: "merge"` pour que les modèles hébergés restent disponibles comme solutions de repli. +Conservez `models.mode: "merge"` afin que les modèles hébergés restent disponibles comme solutions de repli. -Remarque de comportement pour les backends `/v1` locaux / proxifiés : +Remarque de comportement pour les backends `/v1` locaux/proxifiés : -- OpenClaw les traite comme des routes de proxy compatibles OpenAI, et non comme des points de terminaison OpenAI natifs -- le façonnage de requête propre à OpenAI natif ne s’applique pas ici : pas de - `service_tier`, pas de `store` Responses, pas de façonnage de payload de compatibilité de raisonnement OpenAI, - et pas d’indices de cache de prompt -- les en-têtes d’attribution OpenClaw masqués (`originator`, `version`, `User-Agent`) - ne sont pas injectés sur ces URL de proxy personnalisées +- OpenClaw les traite comme des routes compatibles OpenAI de type proxy, et non comme des points de terminaison OpenAI natifs +- la mise en forme des requêtes propre à OpenAI natif ne s’applique pas ici : pas de `service_tier`, pas de `store` Responses, pas de mise en forme de payload de compatibilité de raisonnement OpenAI, et pas d’indices de cache de prompt +- les en-têtes d’attribution OpenClaw cachés (`originator`, `version`, `User-Agent`) ne sont pas injectés sur ces URL de proxy personnalisées -Remarques de compatibilité pour les backends compatibles OpenAI plus stricts : +Notes de compatibilité pour les backends compatibles OpenAI plus stricts : -- Certains serveurs n’acceptent que `messages[].content` sous forme de chaîne sur Chat Completions, et non - des tableaux structurés de parties de contenu. Définissez - `models.providers..models[].compat.requiresStringContent: true` pour - ces points de terminaison. -- Certains backends locaux plus petits ou plus stricts sont instables avec la forme complète - de prompt du runtime d’agent d’OpenClaw, en particulier lorsque des schémas d’outils sont inclus. Si le - backend fonctionne pour de petits appels directs à `/v1/chat/completions` mais échoue sur des tours d’agent - OpenClaw normaux, essayez d’abord - `models.providers..models[].compat.supportsTools: false`. -- Si le backend échoue toujours uniquement sur des exécutions OpenClaw plus volumineuses, le problème restant - provient généralement de la capacité du modèle/serveur en amont ou d’un bug du backend, et non de la - couche de transport d’OpenClaw. +- Certains serveurs n’acceptent que `messages[].content` sous forme de chaîne sur Chat Completions, et non des tableaux structurés de parties de contenu. Définissez `models.providers..models[].compat.requiresStringContent: true` pour ces points de terminaison. +- Certains backends locaux plus petits ou plus stricts sont instables avec la forme complète du prompt de l’environnement d’exécution agent d’OpenClaw, en particulier lorsque des schémas d’outils sont inclus. Si le backend fonctionne pour de petits appels directs `/v1/chat/completions` mais échoue sur des tours agent OpenClaw normaux, essayez d’abord `agents.defaults.localModelMode: "lean"` pour supprimer les outils par défaut lourds comme `browser`, `cron` et `message` ; si cela échoue encore, essayez `models.providers..models[].compat.supportsTools: false`. +- Si le backend échoue encore uniquement sur des exécutions OpenClaw plus importantes, le problème restant est généralement lié à la capacité du modèle/serveur en amont ou à un bug du backend, pas à la couche de transport d’OpenClaw. ## Dépannage -- La Gateway peut atteindre le proxy ? `curl http://127.0.0.1:1234/v1/models`. -- Modèle LM Studio déchargé ? Rechargez-le ; le démarrage à froid est une cause fréquente de « blocage ». -- OpenClaw avertit lorsque la fenêtre de contexte détectée est inférieure à **32k** et bloque en dessous de **16k**. Si vous rencontrez ce précontrôle, augmentez la limite de contexte du serveur/modèle ou choisissez un modèle plus grand. +- Le Gateway peut-il atteindre le proxy ? `curl http://127.0.0.1:1234/v1/models`. +- Modèle LM Studio déchargé ? Rechargez-le ; un démarrage à froid est une cause fréquente de « blocage ». +- OpenClaw avertit lorsque la fenêtre de contexte détectée est inférieure à **32k** et bloque en dessous de **16k**. Si vous atteignez ce précontrôle, augmentez la limite de contexte du serveur/modèle ou choisissez un modèle plus grand. - Erreurs de contexte ? Réduisez `contextWindow` ou augmentez la limite de votre serveur. - Le serveur compatible OpenAI renvoie `messages[].content ... expected a string` ? Ajoutez `compat.requiresStringContent: true` sur cette entrée de modèle. -- De petits appels directs à `/v1/chat/completions` fonctionnent, mais `openclaw infer model run` +- Les petits appels directs `/v1/chat/completions` fonctionnent, mais `openclaw infer model run` échoue sur Gemma ou un autre modèle local ? Désactivez d’abord les schémas d’outils avec - `compat.supportsTools: false`, puis retestez. Si le serveur plante toujours uniquement + `compat.supportsTools: false`, puis testez à nouveau. Si le serveur plante encore uniquement sur des prompts OpenClaw plus volumineux, considérez cela comme une limitation du serveur/modèle en amont. -- Sécurité : les modèles locaux contournent les filtres côté fournisseur ; gardez des agents limités dans leur portée et Compaction activé afin de limiter le rayon d’impact des injections de prompt. +- Sécurité : les modèles locaux contournent les filtres côté fournisseur ; gardez des agents limités et laissez Compaction activé pour limiter le rayon d’impact de l’injection de prompt. diff --git a/docs/fr/help/testing.md b/docs/fr/help/testing.md index d4cd7b2f5..833a22fde 100644 --- a/docs/fr/help/testing.md +++ b/docs/fr/help/testing.md @@ -1,101 +1,103 @@ --- read_when: - - Exécuter les tests localement ou dans CI - - Ajouter des tests de régression pour les bugs de modèle/fournisseur - - Déboguer le comportement de la Gateway + de l’agent -summary: 'Kit de test : suites unitaires/e2e/en direct, exécuteurs Docker, et ce que couvre chaque test' -title: Testირება + - Exécuter les tests en local ou dans CI + - Ajouter des tests de régression pour les bogues de modèle/fournisseur + - Déboguer le comportement de Gateway + agent +summary: 'Kit de test : suites unitaires/e2e/live, exécuteurs Docker, et ce que couvre chaque test' +title: Test en cours x-i18n: - generated_at: "2026-04-13T07:04:09Z" + generated_at: "2026-04-15T06:56:35Z" model: gpt-5.4 provider: openai - source_hash: 3db91b4bc36f626cd014958ec66b08b9cecd9faaa20a5746cd3a49ad4b0b1c38 + source_hash: fbf647a5cf13b5861a3ba0cb367dc816c57f0e9c60d3cd6320da193bfadf5609 source_path: help/testing.md workflow: 15 --- # Tests -OpenClaw comporte trois suites Vitest (unitaire/intégration, e2e, en direct) et un petit ensemble d’exécuteurs Docker. +OpenClaw propose trois suites Vitest (unitaires/intégration, e2e, live) ainsi qu’un petit ensemble d’exécuteurs Docker. -Ce document est un guide « comment nous testons » : +Ce document est un guide « comment nous testons » : - Ce que couvre chaque suite (et ce qu’elle ne couvre délibérément _pas_) -- Les commandes à exécuter pour les flux courants (local, avant push, débogage) -- Comment les tests en direct découvrent les identifiants et sélectionnent les modèles/fournisseurs -- Comment ajouter des régressions pour des problèmes réels de modèle/fournisseur +- Quelles commandes exécuter pour les workflows courants (local, avant push, débogage) +- Comment les tests live découvrent les identifiants et sélectionnent les modèles/fournisseurs +- Comment ajouter des tests de régression pour des problèmes réels de modèle/fournisseur ## Démarrage rapide La plupart du temps : -- Contrôle complet (attendu avant push) : `pnpm build && pnpm check && pnpm test` -- Exécution locale plus rapide de la suite complète sur une machine bien dotée : `pnpm test:max` +- Barrière complète (attendue avant un push) : `pnpm build && pnpm check && pnpm test` +- Exécution plus rapide de la suite complète en local sur une machine bien dimensionnée : `pnpm test:max` - Boucle de surveillance Vitest directe : `pnpm test:watch` -- Le ciblage direct de fichiers route désormais aussi les chemins d’extensions/de canaux : `pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts` -- Préférez d’abord des exécutions ciblées quand vous itérez sur un seul échec. +- Le ciblage direct d’un fichier route désormais aussi les chemins d’extension/canal : `pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts` +- Préférez d’abord les exécutions ciblées lorsque vous itérez sur un seul échec. - Site QA adossé à Docker : `pnpm qa:lab:up` - Voie QA adossée à une VM Linux : `pnpm openclaw qa suite --runner multipass --scenario channel-chat-baseline` -Quand vous touchez aux tests ou voulez plus de confiance : +Quand vous modifiez des tests ou voulez davantage de confiance : -- Contrôle de couverture : `pnpm test:coverage` +- Barrière de couverture : `pnpm test:coverage` - Suite E2E : `pnpm test:e2e` -Quand vous déboguez de vrais fournisseurs/modèles (nécessite de vrais identifiants) : +Lors du débogage de vrais fournisseurs/modèles (nécessite de vrais identifiants) : -- Suite en direct (modèles + sondes Gateway outils/images) : `pnpm test:live` -- Cibler un seul fichier en direct discrètement : `pnpm test:live -- src/agents/models.profiles.live.test.ts` +- Suite live (modèles + sondes Gateway outil/image) : `pnpm test:live` +- Cibler silencieusement un seul fichier live : `pnpm test:live -- src/agents/models.profiles.live.test.ts` -Astuce : quand vous n’avez besoin que d’un seul cas en échec, préférez restreindre les tests en direct via les variables d’environnement de liste d’autorisation décrites ci-dessous. +Astuce : lorsque vous n’avez besoin que d’un seul cas en échec, préférez restreindre les tests live via les variables d’environnement de liste d’autorisation décrites ci-dessous. ## Exécuteurs spécifiques à la QA -Ces commandes se trouvent à côté des suites de test principales lorsque vous avez besoin du réalisme de qa-lab : +Ces commandes viennent compléter les suites de test principales lorsque vous avez besoin du réalisme de qa-lab : - `pnpm openclaw qa suite` - Exécute directement sur l’hôte des scénarios QA adossés au dépôt. - - Exécute par défaut en parallèle plusieurs scénarios sélectionnés avec des workers Gateway isolés, jusqu’à 64 workers ou au nombre de scénarios sélectionnés. Utilisez `--concurrency ` pour ajuster le nombre de workers, ou `--concurrency 1` pour l’ancienne voie sérielle. + - Exécute par défaut plusieurs scénarios sélectionnés en parallèle avec des workers Gateway isolés, jusqu’à 64 workers ou au nombre de scénarios sélectionnés. Utilisez `--concurrency ` pour ajuster le nombre de workers, ou `--concurrency 1` pour l’ancienne voie sérielle. - `pnpm openclaw qa suite --runner multipass` - Exécute la même suite QA dans une VM Linux Multipass jetable. - Conserve le même comportement de sélection de scénarios que `qa suite` sur l’hôte. - Réutilise les mêmes drapeaux de sélection de fournisseur/modèle que `qa suite`. - - Les exécutions en direct transfèrent les entrées d’authentification QA prises en charge qui sont pratiques pour l’invité : - clés de fournisseur basées sur l’environnement, chemin de configuration du fournisseur QA en direct, et `CODEX_HOME` si présent. - - Les répertoires de sortie doivent rester sous la racine du dépôt afin que l’invité puisse réécrire via l’espace de travail monté. - - Écrit le rapport QA + résumé habituels ainsi que les journaux Multipass dans `.artifacts/qa-e2e/...`. + - Les exécutions live transfèrent les entrées d’authentification QA prises en charge qui sont pratiques pour l’invité : + clés de fournisseur basées sur l’environnement, chemin de configuration du fournisseur live QA, et `CODEX_HOME` lorsqu’il est présent. + - Les répertoires de sortie doivent rester sous la racine du dépôt afin que l’invité puisse écrire en retour via l’espace de travail monté. + - Écrit le rapport QA et le résumé habituels, plus les journaux Multipass, sous `.artifacts/qa-e2e/...`. - `pnpm qa:lab:up` - - Démarre le site QA adossé à Docker pour un travail QA de type opérateur. + - Démarre le site QA adossé à Docker pour le travail QA de type opérateur. - `pnpm openclaw qa matrix` - - Exécute la voie QA Matrix en direct contre un homeserver Tuwunel jetable adossé à Docker. - - Provisionne trois utilisateurs Matrix temporaires (`driver`, `sut`, `observer`) ainsi qu’une salle privée, puis démarre un processus enfant de Gateway QA avec le vrai Plugin Matrix comme transport SUT. - - Utilise par défaut l’image Tuwunel stable épinglée `ghcr.io/matrix-construct/tuwunel:v1.5.1`. Remplacez-la avec `OPENCLAW_QA_MATRIX_TUWUNEL_IMAGE` quand vous devez tester une autre image. - - Matrix prend actuellement uniquement en charge `--credential-source env` car la voie provisionne localement des utilisateurs jetables. - - Écrit un rapport QA Matrix, un résumé et un artefact d’événements observés dans `.artifacts/qa-e2e/...`. + - Exécute la voie QA live Matrix sur un homeserver Tuwunel jetable adossé à Docker. + - Cet hôte QA est aujourd’hui réservé au dépôt/au développement. Les installations OpenClaw packagées n’embarquent pas `qa-lab`, elles n’exposent donc pas `openclaw qa`. + - Les checkouts du dépôt chargent directement l’exécuteur intégré ; aucune étape d’installation de Plugin séparée n’est nécessaire. + - Approvisionne trois utilisateurs Matrix temporaires (`driver`, `sut`, `observer`) ainsi qu’un salon privé, puis démarre un enfant de passerelle QA avec le vrai Plugin Matrix comme transport SUT. + - Utilise par défaut l’image Tuwunel stable épinglée `ghcr.io/matrix-construct/tuwunel:v1.5.1`. Remplacez-la avec `OPENCLAW_QA_MATRIX_TUWUNEL_IMAGE` lorsque vous devez tester une autre image. + - Matrix n’expose pas de drapeaux partagés de source d’identifiants, car la voie approvisionne localement des utilisateurs jetables. + - Écrit un rapport QA Matrix, un résumé et un artefact d’événements observés sous `.artifacts/qa-e2e/...`. - `pnpm openclaw qa telegram` - - Exécute la voie QA Telegram en direct contre un vrai groupe privé en utilisant les jetons de bot driver et SUT issus de l’environnement. + - Exécute la voie QA live Telegram sur un vrai groupe privé à l’aide des jetons de bot driver et SUT fournis par l’environnement. - Nécessite `OPENCLAW_QA_TELEGRAM_GROUP_ID`, `OPENCLAW_QA_TELEGRAM_DRIVER_BOT_TOKEN` et `OPENCLAW_QA_TELEGRAM_SUT_BOT_TOKEN`. L’identifiant du groupe doit être l’identifiant numérique du chat Telegram. - - Prend en charge `--credential-source convex` pour des identifiants partagés mutualisés. Utilisez le mode env par défaut, ou définissez `OPENCLAW_QA_CREDENTIAL_SOURCE=convex` pour activer les baux mutualisés. + - Prend en charge `--credential-source convex` pour des identifiants mutualisés en pool. Utilisez le mode environnement par défaut, ou définissez `OPENCLAW_QA_CREDENTIAL_SOURCE=convex` pour activer les baux mutualisés. - Nécessite deux bots distincts dans le même groupe privé, le bot SUT devant exposer un nom d’utilisateur Telegram. - - Pour une observation stable bot-à-bot, activez le mode de communication bot-à-bot dans `@BotFather` pour les deux bots et assurez-vous que le bot driver peut observer le trafic des bots du groupe. - - Écrit un rapport QA Telegram, un résumé et un artefact de messages observés dans `.artifacts/qa-e2e/...`. + - Pour une observation stable entre bots, activez le mode de communication bot-à-bot dans `@BotFather` pour les deux bots et assurez-vous que le bot driver peut observer le trafic des bots du groupe. + - Écrit un rapport QA Telegram, un résumé et un artefact des messages observés sous `.artifacts/qa-e2e/...`. -Les voies de transport en direct partagent un contrat standard afin que les nouveaux transports ne dérivent pas. +Les voies de transport live partagent un contrat standard afin d’éviter toute dérive lors de l’ajout de nouveaux transports : -`qa-channel` reste la large suite QA synthétique et ne fait pas partie de la matrice de couverture des transports en direct. +`qa-channel` reste la suite QA synthétique large et ne fait pas partie de la matrice de couverture des transports live. -| Voie | Canary | Filtrage des mentions | Blocage par liste d’autorisation | Réponse de premier niveau | Reprise après redémarrage | Suivi de fil | Isolement des fils | Observation des réactions | Commande d’aide | -| -------- | ------ | --------------------- | -------------------------------- | ------------------------- | ------------------------- | ------------ | ------------------ | ------------------------- | --------------- | -| Matrix | x | x | x | x | x | x | x | x | | -| Telegram | x | | | | | | | | x | +| Voie | Canary | Filtrage des mentions | Blocage par liste d’autorisation | Réponse de niveau supérieur | Reprise après redémarrage | Suivi de fil | Isolation de fil | Observation des réactions | Commande d’aide | +| -------- | ------ | --------------------- | -------------------------------- | --------------------------- | ------------------------- | ------------ | ---------------- | ------------------------- | --------------- | +| Matrix | x | x | x | x | x | x | x | x | | +| Telegram | x | | | | | | | | x | ### Identifiants Telegram partagés via Convex (v1) -Quand `--credential-source convex` (ou `OPENCLAW_QA_CREDENTIAL_SOURCE=convex`) est activé pour -`openclaw qa telegram`, QA lab acquiert un bail exclusif depuis un pool adossé à Convex, envoie un Heartbeat -pour ce bail pendant l’exécution de la voie, puis libère le bail à l’arrêt. +Lorsque `--credential-source convex` (ou `OPENCLAW_QA_CREDENTIAL_SOURCE=convex`) est activé pour +`openclaw qa telegram`, QA lab acquiert un bail exclusif depuis un pool adossé à Convex, envoie des Heartbeat +pour ce bail tant que la voie est en cours d’exécution, puis libère le bail à l’arrêt. -Squelette de projet Convex de référence : +Structure de référence du projet Convex : - `qa/convex-credential-broker/` @@ -107,7 +109,7 @@ Variables d’environnement requises : - `OPENCLAW_QA_CONVEX_SECRET_CI` pour `ci` - Sélection du rôle d’identifiant : - CLI : `--credential-role maintainer|ci` - - Valeur par défaut via l’environnement : `OPENCLAW_QA_CREDENTIAL_ROLE` (par défaut : `maintainer`) + - Valeur par défaut dans l’environnement : `OPENCLAW_QA_CREDENTIAL_ROLE` (par défaut `maintainer`) Variables d’environnement facultatives : @@ -116,15 +118,15 @@ Variables d’environnement facultatives : - `OPENCLAW_QA_CREDENTIAL_ACQUIRE_TIMEOUT_MS` (par défaut `90000`) - `OPENCLAW_QA_CREDENTIAL_HTTP_TIMEOUT_MS` (par défaut `15000`) - `OPENCLAW_QA_CONVEX_ENDPOINT_PREFIX` (par défaut `/qa-credentials/v1`) -- `OPENCLAW_QA_CREDENTIAL_OWNER_ID` (identifiant de traçage facultatif) -- `OPENCLAW_QA_ALLOW_INSECURE_HTTP=1` autorise les URL Convex `http://` en loopback local uniquement pour le développement strictement local. +- `OPENCLAW_QA_CREDENTIAL_OWNER_ID` (identifiant de trace facultatif) +- `OPENCLAW_QA_ALLOW_INSECURE_HTTP=1` autorise les URL Convex `http://` en loopback pour le développement strictement local. `OPENCLAW_QA_CONVEX_SITE_URL` doit utiliser `https://` en fonctionnement normal. -Les commandes d’administration mainteneur (ajout/suppression/liste dans le pool) nécessitent +Les commandes d’administration pour mainteneurs (ajout/suppression/liste du pool) exigent spécifiquement `OPENCLAW_QA_CONVEX_SECRET_MAINTAINER`. -Aides CLI pour les mainteneurs : +Assistants CLI pour les mainteneurs : ```bash pnpm openclaw qa credentials add --kind telegram --payload-file qa/telegram-credential.json @@ -132,83 +134,88 @@ pnpm openclaw qa credentials list --kind telegram pnpm openclaw qa credentials remove --credential-id ``` -Utilisez `--json` pour une sortie lisible par machine dans les scripts et utilitaires CI. +Utilisez `--json` pour une sortie exploitable par machine dans les scripts et les utilitaires CI. Contrat de point de terminaison par défaut (`OPENCLAW_QA_CONVEX_SITE_URL` + `/qa-credentials/v1`) : - `POST /acquire` - Requête : `{ kind, ownerId, actorRole, leaseTtlMs, heartbeatIntervalMs }` - Succès : `{ status: "ok", credentialId, leaseToken, payload, leaseTtlMs?, heartbeatIntervalMs? }` - - Épuisé/rejouable : `{ status: "error", code: "POOL_EXHAUSTED" | "NO_CREDENTIAL_AVAILABLE", ... }` + - Pool épuisé / cas réessayable : `{ status: "error", code: "POOL_EXHAUSTED" | "NO_CREDENTIAL_AVAILABLE", ... }` - `POST /heartbeat` - Requête : `{ kind, ownerId, actorRole, credentialId, leaseToken, leaseTtlMs }` - Succès : `{ status: "ok" }` (ou `2xx` vide) - `POST /release` - Requête : `{ kind, ownerId, actorRole, credentialId, leaseToken }` - Succès : `{ status: "ok" }` (ou `2xx` vide) -- `POST /admin/add` (secret mainteneur uniquement) +- `POST /admin/add` (secret maintainer uniquement) - Requête : `{ kind, actorId, payload, note?, status? }` - Succès : `{ status: "ok", credential }` -- `POST /admin/remove` (secret mainteneur uniquement) +- `POST /admin/remove` (secret maintainer uniquement) - Requête : `{ credentialId, actorId }` - Succès : `{ status: "ok", changed, credential }` - Garde de bail actif : `{ status: "error", code: "LEASE_ACTIVE", ... }` -- `POST /admin/list` (secret mainteneur uniquement) +- `POST /admin/list` (secret maintainer uniquement) - Requête : `{ kind?, status?, includePayload?, limit? }` - Succès : `{ status: "ok", credentials, count }` -Forme de charge utile pour le type Telegram : +Forme du payload pour le type Telegram : - `{ groupId: string, driverToken: string, sutToken: string }` -- `groupId` doit être une chaîne d’identifiant numérique de chat Telegram. -- `admin/add` valide cette forme pour `kind: "telegram"` et rejette les charges utiles mal formées. +- `groupId` doit être une chaîne représentant un identifiant numérique de chat Telegram. +- `admin/add` valide cette forme pour `kind: "telegram"` et rejette les payloads mal formés. ### Ajouter un canal à la QA Ajouter un canal au système QA Markdown nécessite exactement deux éléments : -1. Un adaptateur de transport pour le canal. +1. Un adaptateur de transport pour ce canal. 2. Un pack de scénarios qui exerce le contrat du canal. -N’ajoutez pas d’exécuteur QA spécifique à un canal lorsque l’exécuteur partagé `qa-lab` peut +N’ajoutez pas une nouvelle racine de commande QA de niveau supérieur lorsque l’hôte partagé `qa-lab` peut prendre en charge le flux. -`qa-lab` prend en charge les mécanismes partagés : +`qa-lab` possède les mécanismes d’hôte partagés : -- démarrage et arrêt de la suite -- concurrence des workers -- écriture des artefacts -- génération de rapport -- exécution des scénarios -- alias de compatibilité pour les anciens scénarios `qa-channel` +- la racine de commande `openclaw qa` +- le démarrage et l’arrêt de la suite +- la concurrence des workers +- l’écriture des artefacts +- la génération des rapports +- l’exécution des scénarios +- les alias de compatibilité pour les anciens scénarios `qa-channel` -L’adaptateur de canal prend en charge le contrat de transport : +Les plugins d’exécuteur possèdent le contrat de transport : -- comment la Gateway est configurée pour ce transport -- comment l’état prêt est vérifié -- comment les événements entrants sont injectés -- comment les messages sortants sont observés -- comment les transcriptions et l’état de transport normalisé sont exposés -- comment les actions adossées au transport sont exécutées -- comment la réinitialisation ou le nettoyage spécifique au transport est géré +- la manière dont `openclaw qa ` est monté sous la racine partagée `qa` +- la manière dont la passerelle est configurée pour ce transport +- la manière dont l’état prêt est vérifié +- la manière dont les événements entrants sont injectés +- la manière dont les messages sortants sont observés +- la manière dont les transcriptions et l’état de transport normalisé sont exposés +- la manière dont les actions adossées au transport sont exécutées +- la manière dont la réinitialisation ou le nettoyage spécifiques au transport sont gérés -Le seuil minimal d’adoption pour un nouveau canal est le suivant : +Le niveau minimal d’adoption pour un nouveau canal est le suivant : -1. Implémenter l’adaptateur de transport sur la jonction partagée `qa-lab`. -2. Enregistrer l’adaptateur dans le registre des transports. -3. Conserver les mécanismes spécifiques au transport dans l’adaptateur ou le harnais du canal. -4. Rédiger ou adapter des scénarios Markdown sous `qa/scenarios/`. -5. Utiliser les aides de scénario génériques pour les nouveaux scénarios. -6. Conserver les alias de compatibilité existants sauf si le dépôt effectue une migration intentionnelle. +1. Conserver `qa-lab` comme propriétaire de la racine partagée `qa`. +2. Implémenter l’exécuteur de transport sur le point d’extension de l’hôte partagé `qa-lab`. +3. Conserver les mécanismes spécifiques au transport à l’intérieur du plugin d’exécuteur ou du harnais de Plugin du canal. +4. Monter l’exécuteur sous la forme `openclaw qa ` au lieu d’enregistrer une racine de commande concurrente. + Les plugins d’exécuteur doivent déclarer `qaRunners` dans `openclaw.plugin.json` et exporter un tableau `qaRunnerCliRegistrations` correspondant depuis `runtime-api.ts`. + Gardez `runtime-api.ts` léger ; l’exécution lazy du CLI et de l’exécuteur doit rester derrière des points d’entrée séparés. +5. Rédiger ou adapter des scénarios Markdown sous `qa/scenarios/`. +6. Utiliser les assistants de scénario génériques pour les nouveaux scénarios. +7. Conserver les alias de compatibilité existants, sauf si le dépôt effectue une migration intentionnelle. La règle de décision est stricte : - Si un comportement peut être exprimé une seule fois dans `qa-lab`, placez-le dans `qa-lab`. -- Si un comportement dépend d’un seul transport de canal, conservez-le dans cet adaptateur ou ce harnais de Plugin. -- Si un scénario a besoin d’une nouvelle capacité que plus d’un canal peut utiliser, ajoutez une aide générique au lieu d’une branche spécifique à un canal dans `suite.ts`. -- Si un comportement n’a de sens que pour un seul transport, conservez le scénario spécifique à ce transport et explicitez-le dans le contrat du scénario. +- Si un comportement dépend d’un seul transport de canal, conservez-le dans ce plugin d’exécuteur ou ce harnais de Plugin. +- Si un scénario nécessite une nouvelle capacité que plus d’un canal peut utiliser, ajoutez un assistant générique plutôt qu’une branche spécifique à un canal dans `suite.ts`. +- Si un comportement n’a de sens que pour un seul transport, gardez le scénario spécifique à ce transport et rendez cela explicite dans le contrat du scénario. -Les noms d’aides génériques préférés pour les nouveaux scénarios sont : +Les noms d’assistants génériques préférés pour les nouveaux scénarios sont : - `waitForTransportReady` - `waitForChannelReady` @@ -223,7 +230,7 @@ Les noms d’aides génériques préférés pour les nouveaux scénarios sont : - `formatTransportTranscript` - `resetTransport` -Des alias de compatibilité restent disponibles pour les scénarios existants, notamment : +Les alias de compatibilité restent disponibles pour les scénarios existants, notamment : - `waitForQaChannelReady` - `waitForOutboundMessage` @@ -231,85 +238,85 @@ Des alias de compatibilité restent disponibles pour les scénarios existants, n - `formatConversationTranscript` - `resetBus` -Le nouveau travail sur les canaux doit utiliser les noms d’aides génériques. -Les alias de compatibilité existent pour éviter une migration en une seule fois, et non comme modèle pour -la rédaction de nouveaux scénarios. +Les nouveaux travaux sur les canaux doivent utiliser les noms d’assistants génériques. +Les alias de compatibilité existent pour éviter une migration brutale, pas comme modèle +pour rédiger de nouveaux scénarios. ## Suites de test (ce qui s’exécute où) -Considérez les suites comme présentant un « réalisme croissant » (et une instabilité/un coût croissants) : +Considérez les suites comme des niveaux de « réalisme croissant » (et de fragilité/coût croissants) : -### Unitaire / intégration (par défaut) +### Unitaires / intégration (par défaut) - Commande : `pnpm test` -- Configuration : dix exécutions séquentielles par fragment (`vitest.full-*.config.ts`) sur les projets Vitest ciblés existants -- Fichiers : inventaires core/unit sous `src/**/*.test.ts`, `packages/**/*.test.ts`, `test/**/*.test.ts`, et les tests Node `ui` autorisés couverts par `vitest.unit.config.ts` +- Configuration : dix exécutions séquentielles de shards (`vitest.full-*.config.ts`) sur les projets Vitest ciblés existants +- Fichiers : inventaires core/unit sous `src/**/*.test.ts`, `packages/**/*.test.ts`, `test/**/*.test.ts`, ainsi que les tests node `ui` autorisés couverts par `vitest.unit.config.ts` - Portée : - Tests unitaires purs - - Tests d’intégration en processus (authentification Gateway, routage, outillage, analyse, configuration) - - Régressions déterministes pour les bugs connus + - Tests d’intégration en processus (authentification Gateway, routage, outils, analyse, configuration) + - Régressions déterministes pour des bogues connus - Attentes : - - S’exécute en CI - - Aucune vraie clé requise + - S’exécute dans CI + - Aucune clé réelle requise - Doit être rapide et stable - Remarque sur les projets : - - `pnpm test` sans ciblage exécute désormais onze petites configurations fragmentées (`core-unit-src`, `core-unit-security`, `core-unit-ui`, `core-unit-support`, `core-support-boundary`, `core-contracts`, `core-bundled`, `core-runtime`, `agentic`, `auto-reply`, `extensions`) au lieu d’un unique processus natif géant de projet racine. Cela réduit le pic de RSS sur les machines chargées et évite que le travail auto-reply/extension n’affame les suites non liées. - - `pnpm test --watch` utilise toujours le graphe de projets natif de `vitest.config.ts`, car une boucle de surveillance multi-fragments n’est pas pratique. - - `pnpm test`, `pnpm test:watch` et `pnpm test:perf:imports` routent d’abord les cibles explicites de fichiers/répertoires via des voies ciblées, de sorte que `pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts` évite le coût complet de démarrage du projet racine. - - `pnpm test:changed` développe les chemins Git modifiés vers ces mêmes voies ciblées quand le diff ne touche que des fichiers source/de test routables ; les modifications de configuration/d’initialisation reviennent toujours à une réexécution large du projet racine. - - Les tests unitaires légers en import depuis les agents, les commandes, les plugins, les aides auto-reply, `plugin-sdk`, et d’autres zones purement utilitaires similaires passent par la voie `unit-fast`, qui ignore `test/setup-openclaw-runtime.ts` ; les fichiers lourds avec état/à forte exécution restent sur les voies existantes. - - Certains fichiers source auxiliaires `plugin-sdk` et `commands` sélectionnés mappent aussi les exécutions en mode changed vers des tests frères explicites dans ces voies légères, afin que les modifications d’aides évitent de relancer toute la suite lourde de ce répertoire. - - `auto-reply` dispose maintenant de trois compartiments dédiés : les aides core de premier niveau, les tests d’intégration `reply.*` de premier niveau, et le sous-arbre `src/auto-reply/reply/**`. Cela garde le travail le plus lourd du harnais de réponse hors des tests peu coûteux sur status/chunk/token. + - `pnpm test` sans ciblage exécute désormais onze configurations de shards plus petites (`core-unit-src`, `core-unit-security`, `core-unit-ui`, `core-unit-support`, `core-support-boundary`, `core-contracts`, `core-bundled`, `core-runtime`, `agentic`, `auto-reply`, `extensions`) au lieu d’un seul énorme processus natif de projet racine. Cela réduit le RSS maximal sur les machines chargées et évite que le travail auto-reply/extension n’affame des suites non liées. + - `pnpm test --watch` utilise toujours le graphe de projets racine natif `vitest.config.ts`, car une boucle de watch multi-shards n’est pas pratique. + - `pnpm test`, `pnpm test:watch` et `pnpm test:perf:imports` routent d’abord les cibles explicites de fichier/répertoire vers des voies ciblées ; ainsi, `pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts` évite le coût de démarrage complet du projet racine. + - `pnpm test:changed` développe les chemins git modifiés vers ces mêmes voies ciblées lorsque le diff ne touche que des fichiers source/test routables ; les modifications de configuration/setup reviennent toujours à une réexécution large du projet racine. + - Les tests unitaires légers à l’import issus des agents, des commandes, des plugins, des assistants auto-reply, de `plugin-sdk` et d’autres zones utilitaires pures sont routés via la voie `unit-fast`, qui ignore `test/setup-openclaw-runtime.ts` ; les fichiers à état/runtime lourd restent sur les voies existantes. + - Certains fichiers source d’assistants `plugin-sdk` et `commands` sélectionnés mappent aussi les exécutions en mode changed vers des tests voisins explicites dans ces voies légères, afin que les modifications d’assistants évitent de relancer toute la suite lourde pour ce répertoire. + - `auto-reply` dispose désormais de trois compartiments dédiés : assistants core de niveau supérieur, tests d’intégration `reply.*` de niveau supérieur, et sous-arborescence `src/auto-reply/reply/**`. Cela garde le travail de harnais de réponse le plus lourd hors des tests économiques de statut/fragment/token. - Remarque sur l’exécuteur embarqué : - - Lorsque vous modifiez les entrées de découverte des outils de message ou le contexte d’exécution de Compaction, + - Lorsque vous modifiez les entrées de découverte de message-tool ou le contexte runtime de Compaction, conservez les deux niveaux de couverture. - - Ajoutez des régressions d’aide ciblées pour les limites pures de routage/normalisation. - - Gardez également en bon état les suites d’intégration de l’exécuteur embarqué : + - Ajoutez des régressions ciblées pour les assistants aux frontières pures de routage/normalisation. + - Gardez également saines les suites d’intégration de l’exécuteur embarqué : `src/agents/pi-embedded-runner/compact.hooks.test.ts`, `src/agents/pi-embedded-runner/run.overflow-compaction.test.ts`, et `src/agents/pi-embedded-runner/run.overflow-compaction.loop.test.ts`. - - Ces suites vérifient que les identifiants ciblés et le comportement de Compaction traversent toujours - les vrais chemins `run.ts` / `compact.ts` ; les tests limités aux aides ne constituent pas - un substitut suffisant à ces chemins d’intégration. + - Ces suites vérifient que les identifiants ciblés et le comportement de Compaction continuent + de traverser les vrais chemins `run.ts` / `compact.ts` ; des tests limités aux assistants ne + suffisent pas à remplacer ces chemins d’intégration. - Remarque sur le pool : - La configuration Vitest de base utilise désormais `threads` par défaut. - - La configuration Vitest partagée fixe aussi `isolate: false` et utilise l’exécuteur non isolé sur les projets racine, e2e et live. - - La voie UI racine conserve sa configuration `jsdom` et son optimiseur, mais s’exécute maintenant aussi sur l’exécuteur partagé non isolé. - - Chaque fragment `pnpm test` hérite des mêmes valeurs par défaut `threads` + `isolate: false` de la configuration Vitest partagée. - - Le lanceur partagé `scripts/run-vitest.mjs` ajoute désormais aussi `--no-maglev` par défaut aux processus enfants Node de Vitest afin de réduire le churn de compilation V8 pendant les grosses exécutions locales. Définissez `OPENCLAW_VITEST_ENABLE_MAGLEV=1` si vous devez comparer avec le comportement V8 standard. + - La configuration Vitest partagée fixe aussi `isolate: false` et utilise l’exécuteur non isolé dans les projets racine, les configurations e2e et live. + - La voie UI racine conserve sa configuration et son optimiseur `jsdom`, mais s’exécute désormais elle aussi sur l’exécuteur partagé non isolé. + - Chaque shard `pnpm test` hérite des mêmes valeurs par défaut `threads` + `isolate: false` depuis la configuration Vitest partagée. + - Le lanceur partagé `scripts/run-vitest.mjs` ajoute désormais aussi `--no-maglev` par défaut aux processus Node enfants de Vitest afin de réduire le churn de compilation V8 lors de grosses exécutions locales. Définissez `OPENCLAW_VITEST_ENABLE_MAGLEV=1` si vous devez comparer avec le comportement V8 standard. - Remarque sur l’itération locale rapide : - - `pnpm test:changed` passe par des voies ciblées lorsque les chemins modifiés correspondent proprement à une suite plus petite. - - `pnpm test:max` et `pnpm test:changed:max` conservent le même comportement de routage, simplement avec un plafond de workers plus élevé. - - La mise à l’échelle automatique des workers locaux est désormais volontairement prudente et ralentit aussi lorsque la charge moyenne de l’hôte est déjà élevée, afin que plusieurs exécutions Vitest simultanées causent moins de dégâts par défaut. - - La configuration Vitest de base marque les fichiers de projets/configuration comme `forceRerunTriggers` afin que les réexécutions en mode changed restent correctes lorsque le câblage des tests change. - - La configuration garde `OPENCLAW_VITEST_FS_MODULE_CACHE` activé sur les hôtes pris en charge ; définissez `OPENCLAW_VITEST_FS_MODULE_CACHE_PATH=/abs/path` si vous voulez un emplacement de cache explicite pour le profilage direct. + - `pnpm test:changed` passe par des voies ciblées lorsque les chemins modifiés se mappent proprement à une suite plus petite. + - `pnpm test:max` et `pnpm test:changed:max` conservent le même comportement de routage, simplement avec une limite de workers plus élevée. + - L’auto-dimensionnement local des workers est désormais volontairement conservateur et ralentit aussi lorsque la charge moyenne de l’hôte est déjà élevée, afin que plusieurs exécutions Vitest concurrentes fassent moins de dégâts par défaut. + - La configuration Vitest de base marque les projets/fichiers de configuration comme `forceRerunTriggers` afin que les réexécutions en mode changed restent correctes lorsque le câblage des tests change. + - La configuration garde `OPENCLAW_VITEST_FS_MODULE_CACHE` activé sur les hôtes pris en charge ; définissez `OPENCLAW_VITEST_FS_MODULE_CACHE_PATH=/abs/path` si vous voulez un emplacement de cache explicite pour un profilage direct. - Remarque sur le débogage des performances : - - `pnpm test:perf:imports` active les rapports de durée d’import Vitest ainsi que la sortie détaillée des imports. + - `pnpm test:perf:imports` active le rapport de durée d’import Vitest ainsi que la sortie de ventilation des imports. - `pnpm test:perf:imports:changed` limite cette même vue de profilage aux fichiers modifiés depuis `origin/main`. -- `pnpm test:perf:changed:bench -- --ref ` compare le `test:changed` routé avec le chemin natif du projet racine pour ce diff validé et affiche le temps total ainsi que le RSS max macOS. -- `pnpm test:perf:changed:bench -- --worktree` mesure l’arbre de travail modifié actuel en routant la liste des fichiers changés via `scripts/test-projects.mjs` et la configuration Vitest racine. - - `pnpm test:perf:profile:main` écrit un profil CPU du thread principal pour les surcoûts de démarrage et de transformation Vitest/Vite. - - `pnpm test:perf:profile:runner` écrit des profils CPU+tas de l’exécuteur pour la suite unitaire avec le parallélisme des fichiers désactivé. +- `pnpm test:perf:changed:bench -- --ref ` compare `test:changed` routé au chemin natif du projet racine pour ce diff validé et affiche le temps réel ainsi que le RSS maximal macOS. +- `pnpm test:perf:changed:bench -- --worktree` mesure l’arbre de travail sale actuel en routant la liste des fichiers modifiés via `scripts/test-projects.mjs` et la configuration Vitest racine. + - `pnpm test:perf:profile:main` écrit un profil CPU du thread principal pour le démarrage de Vitest/Vite et le coût des transformations. + - `pnpm test:perf:profile:runner` écrit des profils CPU+heap de l’exécuteur pour la suite unitaire avec le parallélisme de fichiers désactivé. ### E2E (smoke Gateway) - Commande : `pnpm test:e2e` - Configuration : `vitest.e2e.config.ts` - Fichiers : `src/**/*.e2e.test.ts`, `test/**/*.e2e.test.ts` -- Valeurs par défaut d’exécution : - - Utilise Vitest `threads` avec `isolate: false`, en cohérence avec le reste du dépôt. +- Valeurs d’exécution par défaut : + - Utilise `threads` de Vitest avec `isolate: false`, comme dans le reste du dépôt. - Utilise des workers adaptatifs (CI : jusqu’à 2, local : 1 par défaut). - - S’exécute en mode silencieux par défaut pour réduire le surcoût d’E/S console. + - S’exécute en mode silencieux par défaut pour réduire le coût des E/S console. - Remplacements utiles : - `OPENCLAW_E2E_WORKERS=` pour forcer le nombre de workers (plafonné à 16). - `OPENCLAW_E2E_VERBOSE=1` pour réactiver la sortie console détaillée. - Portée : - - Comportement bout en bout multi-instance de la Gateway - - Surfaces WebSocket/HTTP, appairage de nœuds et réseau plus lourd + - Comportement end-to-end Gateway multi-instance + - Surfaces WebSocket/HTTP, appairage des nœuds et réseau plus lourd - Attentes : - - S’exécute en CI (lorsqu’activé dans le pipeline) - - Aucune vraie clé requise - - Davantage de composants mobiles que les tests unitaires (peut être plus lent) + - S’exécute dans CI (lorsqu’activé dans le pipeline) + - Aucune clé réelle requise + - Davantage de pièces en mouvement que les tests unitaires (peut être plus lent) ### E2E : smoke du backend OpenShell @@ -317,16 +324,16 @@ Considérez les suites comme présentant un « réalisme croissant » (et une - Fichier : `test/openshell-sandbox.e2e.test.ts` - Portée : - Démarre sur l’hôte une Gateway OpenShell isolée via Docker - - Crée un bac à sable à partir d’un Dockerfile local temporaire - - Exerce le backend OpenShell d’OpenClaw via de vrais `sandbox ssh-config` + exécution SSH + - Crée un bac à sable depuis un Dockerfile local temporaire + - Exerce le backend OpenShell d’OpenClaw via un vrai `sandbox ssh-config` + exécution SSH - Vérifie le comportement du système de fichiers canonique distant via le pont fs du bac à sable - Attentes : - - Uniquement sur activation explicite ; ne fait pas partie de l’exécution par défaut `pnpm test:e2e` + - Participation explicite uniquement ; ne fait pas partie de l’exécution par défaut de `pnpm test:e2e` - Nécessite un CLI `openshell` local ainsi qu’un démon Docker fonctionnel - - Utilise `HOME` / `XDG_CONFIG_HOME` isolés, puis détruit la Gateway et le bac à sable de test + - Utilise un `HOME` / `XDG_CONFIG_HOME` isolé, puis détruit la Gateway et le bac à sable de test - Remplacements utiles : - - `OPENCLAW_E2E_OPENSHELL=1` pour activer le test lors de l’exécution manuelle de la suite e2e plus large - - `OPENCLAW_E2E_OPENSHELL_COMMAND=/path/to/openshell` pour pointer vers un binaire CLI non standard ou un script wrapper + - `OPENCLAW_E2E_OPENSHELL=1` pour activer le test lors d’une exécution manuelle de la suite e2e plus large + - `OPENCLAW_E2E_OPENSHELL_COMMAND=/path/to/openshell` pour pointer vers un binaire CLI non par défaut ou un script wrapper ### Live (vrais fournisseurs + vrais modèles) @@ -335,56 +342,56 @@ Considérez les suites comme présentant un « réalisme croissant » (et une - Fichiers : `src/**/*.live.test.ts` - Par défaut : **activé** par `pnpm test:live` (définit `OPENCLAW_LIVE_TEST=1`) - Portée : - - « Est-ce que ce fournisseur/modèle fonctionne réellement _aujourd’hui_ avec de vrais identifiants ? » - - Détecter les changements de format fournisseur, les particularités d’appel d’outils, les problèmes d’authentification et le comportement de limitation de débit + - « Ce fournisseur/modèle fonctionne-t-il vraiment _aujourd’hui_ avec de vrais identifiants ? » + - Détecter les changements de format des fournisseurs, les particularités d’appel d’outil, les problèmes d’authentification et le comportement de limitation de débit - Attentes : - - Par conception, pas stable en CI (vrais réseaux, vraies politiques fournisseurs, quotas, pannes) - - Coûte de l’argent / consomme des quotas - - Préférez exécuter des sous-ensembles ciblés plutôt que « tout » + - Pas stable en CI par conception (vrais réseaux, vraies politiques de fournisseur, quotas, pannes) + - Coûte de l’argent / consomme les limites de débit + - Préférez exécuter des sous-ensembles restreints plutôt que « tout » - Les exécutions live chargent `~/.profile` pour récupérer les clés API manquantes. -- Par défaut, les exécutions live isolent toujours `HOME` et copient le matériel de configuration/d’authentification dans un home de test temporaire afin que les fixtures unitaires ne puissent pas modifier votre vrai `~/.openclaw`. -- Définissez `OPENCLAW_LIVE_USE_REAL_HOME=1` uniquement lorsque vous avez intentionnellement besoin que les tests live utilisent votre vrai répertoire home. -- `pnpm test:live` utilise désormais par défaut un mode plus silencieux : il conserve la sortie de progression `[live] ...`, mais supprime l’avis supplémentaire sur `~/.profile` et masque les journaux de démarrage de la Gateway / le bruit Bonjour. Définissez `OPENCLAW_LIVE_TEST_QUIET=0` si vous voulez récupérer les journaux de démarrage complets. -- Rotation de clés API (spécifique au fournisseur) : définissez `*_API_KEYS` avec un format virgule/point-virgule ou `*_API_KEY_1`, `*_API_KEY_2` (par exemple `OPENAI_API_KEYS`, `ANTHROPIC_API_KEYS`, `GEMINI_API_KEYS`) ou un remplacement par live via `OPENCLAW_LIVE_*_KEY` ; les tests réessaient sur les réponses de limitation de débit. +- Par défaut, les exécutions live isolent toujours `HOME` et copient le matériel de configuration/authentification dans un répertoire temporaire de test afin que les fixtures unitaires ne puissent pas modifier votre vrai `~/.openclaw`. +- Définissez `OPENCLAW_LIVE_USE_REAL_HOME=1` seulement lorsque vous avez intentionnellement besoin que les tests live utilisent votre vrai répertoire personnel. +- `pnpm test:live` utilise désormais par défaut un mode plus silencieux : il conserve la sortie de progression `[live] ...`, mais masque l’avis supplémentaire sur `~/.profile` et coupe les journaux de bootstrap Gateway / le bruit Bonjour. Définissez `OPENCLAW_LIVE_TEST_QUIET=0` si vous voulez récupérer les journaux de démarrage complets. +- Rotation des clés API (spécifique au fournisseur) : définissez `*_API_KEYS` au format virgule/point-virgule ou `*_API_KEY_1`, `*_API_KEY_2` (par exemple `OPENAI_API_KEYS`, `ANTHROPIC_API_KEYS`, `GEMINI_API_KEYS`) ou utilisez un remplacement par live via `OPENCLAW_LIVE_*_KEY` ; les tests réessaient en cas de réponses de limitation de débit. - Sortie de progression/Heartbeat : - - Les suites live émettent désormais des lignes de progression vers stderr afin que les longs appels fournisseur restent visiblement actifs même lorsque la capture console Vitest est silencieuse. - - `vitest.live.config.ts` désactive l’interception de la console par Vitest afin que les lignes de progression fournisseur/Gateway soient diffusées immédiatement pendant les exécutions live. - - Ajustez les Heartbeat de modèle direct avec `OPENCLAW_LIVE_HEARTBEAT_MS`. - - Ajustez les Heartbeat Gateway/sonde avec `OPENCLAW_LIVE_GATEWAY_HEARTBEAT_MS`. + - Les suites live émettent désormais des lignes de progression vers stderr afin que les appels longs aux fournisseurs restent visiblement actifs même lorsque la capture de console Vitest est silencieuse. + - `vitest.live.config.ts` désactive l’interception de console de Vitest afin que les lignes de progression fournisseur/Gateway soient diffusées immédiatement pendant les exécutions live. + - Réglez les Heartbeat de modèle direct avec `OPENCLAW_LIVE_HEARTBEAT_MS`. + - Réglez les Heartbeat Gateway/sonde avec `OPENCLAW_LIVE_GATEWAY_HEARTBEAT_MS`. ## Quelle suite dois-je exécuter ? Utilisez ce tableau de décision : - Modification de logique/tests : exécutez `pnpm test` (et `pnpm test:coverage` si vous avez beaucoup modifié) -- Modification du réseau Gateway / protocole WS / appairage : ajoutez `pnpm test:e2e` -- Débogage de « mon bot est hors service » / échecs spécifiques à un fournisseur / appel d’outils : exécutez un `pnpm test:live` restreint +- Modifications du réseau Gateway / protocole WS / appairage : ajoutez `pnpm test:e2e` +- Débogage de « mon bot est hors service » / échecs spécifiques au fournisseur / appel d’outil : exécutez un `pnpm test:live` restreint -## Live : balayage des capacités de nœud Android +## Live : balayage des capacités du nœud Android - Test : `src/gateway/android-node.capabilities.live.test.ts` - Script : `pnpm android:test:integration` -- Objectif : invoquer **chaque commande actuellement annoncée** par un nœud Android connecté et valider le comportement contractuel des commandes. +- Objectif : invoquer **chaque commande actuellement annoncée** par un nœud Android connecté et vérifier le comportement du contrat de commande. - Portée : - - Préconditions/configuration manuelle (la suite n’installe, n’exécute ni n’apparie l’application). - - Validation commande par commande de `node.invoke` Gateway pour le nœud Android sélectionné. + - Configuration préalable/manuelle (la suite n’installe pas, ne lance pas et n’apparie pas l’application). + - Validation `node.invoke` Gateway commande par commande pour le nœud Android sélectionné. - Préconfiguration requise : - Application Android déjà connectée et appairée à la Gateway. - Application maintenue au premier plan. - - Permissions/consentement de capture accordés pour les capacités que vous attendez comme réussies. -- Remplacements de cible facultatifs : + - Permissions/consentement de capture accordés pour les capacités que vous vous attendez à voir réussir. +- Remplacements facultatifs de cible : - `OPENCLAW_ANDROID_NODE_ID` ou `OPENCLAW_ANDROID_NODE_NAME`. - `OPENCLAW_ANDROID_GATEWAY_URL` / `OPENCLAW_ANDROID_GATEWAY_TOKEN` / `OPENCLAW_ANDROID_GATEWAY_PASSWORD`. - Détails complets de la configuration Android : [Application Android](/fr/platforms/android) -## Live : smoke de modèle (clés de profil) +## Live : smoke des modèles (clés de profil) -Les tests live sont divisés en deux couches afin que nous puissions isoler les échecs : +Les tests live sont divisés en deux couches afin de pouvoir isoler les échecs : -- « Modèle direct » nous indique si le fournisseur/modèle peut répondre tout court avec la clé donnée. -- « Gateway smoke » nous indique si le pipeline complet Gateway+agent fonctionne pour ce modèle (sessions, historique, outils, politique de bac à sable, etc.). +- « Modèle direct » nous indique si le fournisseur/modèle peut répondre tout court avec la clé donnée. +- « Gateway smoke » nous indique si tout le pipeline gateway+agent fonctionne pour ce modèle (sessions, historique, outils, politique de sandbox, etc.). -### Couche 1 : complétion de modèle directe (sans Gateway) +### Couche 1 : complétion directe du modèle (sans gateway) - Test : `src/agents/models.profiles.live.test.ts` - Objectif : @@ -393,34 +400,34 @@ Les tests live sont divisés en deux couches afin que nous puissions isoler les - Exécuter une petite complétion par modèle (et des régressions ciblées si nécessaire) - Comment l’activer : - `pnpm test:live` (ou `OPENCLAW_LIVE_TEST=1` si vous invoquez Vitest directement) -- Définissez `OPENCLAW_LIVE_MODELS=modern` (ou `all`, alias de modern) pour réellement exécuter cette suite ; sinon elle est ignorée afin de garder `pnpm test:live` centré sur le smoke Gateway +- Définissez `OPENCLAW_LIVE_MODELS=modern` (ou `all`, alias de modern) pour réellement exécuter cette suite ; sinon elle est ignorée afin que `pnpm test:live` reste centré sur le smoke Gateway - Comment sélectionner les modèles : - `OPENCLAW_LIVE_MODELS=modern` pour exécuter la liste d’autorisation moderne (Opus/Sonnet 4.6+, GPT-5.x + Codex, Gemini 3, GLM 4.7, MiniMax M2.7, Grok 4) - `OPENCLAW_LIVE_MODELS=all` est un alias de la liste d’autorisation moderne - ou `OPENCLAW_LIVE_MODELS="openai/gpt-5.4,anthropic/claude-opus-4-6,..."` (liste d’autorisation séparée par des virgules) - - Les balayages modern/all utilisent par défaut un plafond organisé à fort signal ; définissez `OPENCLAW_LIVE_MAX_MODELS=0` pour un balayage moderne exhaustif ou une valeur positive pour un plafond plus réduit. + - Les balayages modern/all utilisent par défaut une limite sélectionnée à fort signal ; définissez `OPENCLAW_LIVE_MAX_MODELS=0` pour un balayage moderne exhaustif ou une valeur positive pour une limite plus petite. - Comment sélectionner les fournisseurs : - `OPENCLAW_LIVE_PROVIDERS="google,google-antigravity,google-gemini-cli"` (liste d’autorisation séparée par des virgules) - D’où viennent les clés : - - Par défaut : magasin de profils et replis env - - Définissez `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` pour imposer **uniquement le magasin de profils** + - Par défaut : magasin de profils et replis via l’environnement + - Définissez `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` pour imposer le **magasin de profils** uniquement - Pourquoi cela existe : - - Sépare « l’API fournisseur est cassée / la clé est invalide » de « le pipeline d’agent Gateway est cassé » - - Contient de petites régressions isolées (exemple : flux OpenAI Responses/Codex Responses pour relecture de raisonnement + appels d’outils) + - Sépare « l’API du fournisseur est cassée / la clé est invalide » de « le pipeline d’agent Gateway est cassé » + - Contient de petites régressions isolées (exemple : rejeu de raisonnement OpenAI Responses/Codex Responses + flux d’appel d’outil) -### Couche 2 : smoke Gateway + agent de développement (ce que fait réellement « @openclaw ») +### Couche 2 : smoke Gateway + agent dev (ce que fait réellement "@openclaw") - Test : `src/gateway/gateway-models.profiles.live.test.ts` - Objectif : - Démarrer une Gateway en processus - - Créer/modifier une session `agent:dev:*` (remplacement du modèle à chaque exécution) - - Parcourir les modèles avec clés et vérifier : + - Créer/modifier une session `agent:dev:*` (remplacement de modèle à chaque exécution) + - Itérer sur les modèles avec clés et vérifier : - une réponse « significative » (sans outils) - - qu’une invocation réelle d’outil fonctionne (sonde de lecture) - - des sondes d’outils supplémentaires facultatives (sonde exec+read) - - que les chemins de régression OpenAI (tool-call-only → suivi) continuent de fonctionner -- Détails des sondes (afin de pouvoir expliquer rapidement les échecs) : - - sonde `read` : le test écrit un fichier nonce dans l’espace de travail et demande à l’agent de le `read`, puis de renvoyer le nonce. + - qu’un véritable appel d’outil fonctionne (sonde de lecture) + - des sondes d’outil supplémentaires facultatives (sonde exec+lecture) + - que les chemins de régression OpenAI (appel d’outil seul → suivi) continuent de fonctionner +- Détails des sondes (pour pouvoir expliquer rapidement les échecs) : + - sonde `read` : le test écrit un fichier nonce dans l’espace de travail et demande à l’agent de le `read` puis de renvoyer le nonce. - sonde `exec+read` : le test demande à l’agent d’écrire un nonce dans un fichier temporaire via `exec`, puis de le relire via `read`. - sonde image : le test joint un PNG généré (chat + code aléatoire) et attend que le modèle renvoie `cat `. - Référence d’implémentation : `src/gateway/gateway-models.profiles.live.test.ts` et `src/gateway/live-image-probe.ts`. @@ -428,18 +435,18 @@ Les tests live sont divisés en deux couches afin que nous puissions isoler les - `pnpm test:live` (ou `OPENCLAW_LIVE_TEST=1` si vous invoquez Vitest directement) - Comment sélectionner les modèles : - Par défaut : liste d’autorisation moderne (Opus/Sonnet 4.6+, GPT-5.x + Codex, Gemini 3, GLM 4.7, MiniMax M2.7, Grok 4) - - `OPENCLAW_LIVE_GATEWAY_MODELS=all` est un alias pour la liste d’autorisation moderne + - `OPENCLAW_LIVE_GATEWAY_MODELS=all` est un alias de la liste d’autorisation moderne - Ou définissez `OPENCLAW_LIVE_GATEWAY_MODELS="provider/model"` (ou une liste séparée par des virgules) pour restreindre - - Les balayages Gateway modern/all utilisent par défaut un plafond organisé à fort signal ; définissez `OPENCLAW_LIVE_GATEWAY_MAX_MODELS=0` pour un balayage moderne exhaustif ou une valeur positive pour un plafond plus réduit. -- Comment sélectionner les fournisseurs (éviter « OpenRouter tout ») : + - Les balayages gateway modern/all utilisent par défaut une limite sélectionnée à fort signal ; définissez `OPENCLAW_LIVE_GATEWAY_MAX_MODELS=0` pour un balayage moderne exhaustif ou une valeur positive pour une limite plus petite. +- Comment sélectionner les fournisseurs (éviter « tout OpenRouter ») : - `OPENCLAW_LIVE_GATEWAY_PROVIDERS="google,google-antigravity,google-gemini-cli,openai,anthropic,zai,minimax"` (liste d’autorisation séparée par des virgules) -- Les sondes d’outils + d’image sont toujours activées dans ce test live : +- Les sondes d’outil + image sont toujours activées dans ce test live : - sonde `read` + sonde `exec+read` (stress des outils) - - la sonde image s’exécute lorsque le modèle annonce la prise en charge d’entrée image - - Flux (niveau élevé) : + - la sonde image s’exécute lorsque le modèle annonce la prise en charge des entrées image + - Flux (vue d’ensemble) : - Le test génère un petit PNG avec « CAT » + un code aléatoire (`src/gateway/live-image-probe.ts`) - L’envoie via `agent` `attachments: [{ mimeType: "image/png", content: "" }]` - - La Gateway analyse les pièces jointes dans `images[]` (`src/gateway/server-methods/agent.ts` + `src/gateway/chat-attachments.ts`) + - Gateway analyse les pièces jointes en `images[]` (`src/gateway/server-methods/agent.ts` + `src/gateway/chat-attachments.ts`) - L’agent embarqué transmet au modèle un message utilisateur multimodal - Vérification : la réponse contient `cat` + le code (tolérance OCR : petites erreurs autorisées) @@ -454,8 +461,8 @@ openclaw models list --json - Test : `src/gateway/gateway-cli-backend.live.test.ts` - Objectif : valider le pipeline Gateway + agent à l’aide d’un backend CLI local, sans toucher à votre configuration par défaut. -- Les valeurs par défaut du smoke spécifiques au backend se trouvent avec la définition `cli-backend.ts` de l’extension propriétaire. -- Activer : +- Les valeurs par défaut de smoke spécifiques au backend se trouvent dans la définition `cli-backend.ts` de l’extension propriétaire. +- Activation : - `pnpm test:live` (ou `OPENCLAW_LIVE_TEST=1` si vous invoquez Vitest directement) - `OPENCLAW_LIVE_CLI_BACKEND=1` - Valeurs par défaut : @@ -465,11 +472,11 @@ openclaw models list --json - `OPENCLAW_LIVE_CLI_BACKEND_MODEL="codex-cli/gpt-5.4"` - `OPENCLAW_LIVE_CLI_BACKEND_COMMAND="/full/path/to/codex"` - `OPENCLAW_LIVE_CLI_BACKEND_ARGS='["exec","--json","--color","never","--sandbox","read-only","--skip-git-repo-check"]'` - - `OPENCLAW_LIVE_CLI_BACKEND_IMAGE_PROBE=1` pour envoyer une vraie pièce jointe image (les chemins sont injectés dans l’invite). - - `OPENCLAW_LIVE_CLI_BACKEND_IMAGE_ARG="--image"` pour transmettre les chemins des fichiers image comme arguments CLI au lieu d’une injection dans l’invite. + - `OPENCLAW_LIVE_CLI_BACKEND_IMAGE_PROBE=1` pour envoyer une véritable pièce jointe image (les chemins sont injectés dans le prompt). + - `OPENCLAW_LIVE_CLI_BACKEND_IMAGE_ARG="--image"` pour passer les chemins des fichiers image comme arguments CLI au lieu d’une injection dans le prompt. - `OPENCLAW_LIVE_CLI_BACKEND_IMAGE_MODE="repeat"` (ou `"list"`) pour contrôler la manière dont les arguments image sont transmis lorsque `IMAGE_ARG` est défini. - `OPENCLAW_LIVE_CLI_BACKEND_RESUME_PROBE=1` pour envoyer un second tour et valider le flux de reprise. - - `OPENCLAW_LIVE_CLI_BACKEND_MODEL_SWITCH_PROBE=0` pour désactiver la sonde par défaut de continuité dans une même session Claude Sonnet -> Opus (définissez-la à `1` pour l’imposer lorsque le modèle sélectionné prend en charge une cible de bascule). + - `OPENCLAW_LIVE_CLI_BACKEND_MODEL_SWITCH_PROBE=0` pour désactiver la sonde par défaut de continuité dans une même session Claude Sonnet -> Opus (définissez `1` pour la forcer lorsque le modèle sélectionné prend en charge une cible de bascule). Exemple : @@ -485,7 +492,7 @@ Recette Docker : pnpm test:docker:live-cli-backend ``` -Recettes Docker à fournisseur unique : +Recettes Docker pour un seul fournisseur : ```bash pnpm test:docker:live-cli-backend:claude @@ -497,27 +504,27 @@ pnpm test:docker:live-cli-backend:gemini Remarques : - L’exécuteur Docker se trouve dans `scripts/test-live-cli-backend-docker.sh`. -- Il exécute le smoke live du backend CLI dans l’image Docker du dépôt en tant qu’utilisateur non root `node`. -- Il résout les métadonnées du smoke CLI depuis l’extension propriétaire, puis installe le paquet CLI Linux correspondant (`@anthropic-ai/claude-code`, `@openai/codex` ou `@google/gemini-cli`) dans un préfixe inscriptible mis en cache à `OPENCLAW_DOCKER_CLI_TOOLS_DIR` (par défaut : `~/.cache/openclaw/docker-cli-tools`). -- `pnpm test:docker:live-cli-backend:claude-subscription` nécessite une authentification OAuth portable à l’abonnement Claude Code via soit `~/.claude/.credentials.json` avec `claudeAiOauth.subscriptionType`, soit `CLAUDE_CODE_OAUTH_TOKEN` depuis `claude setup-token`. Il vérifie d’abord directement `claude -p` dans Docker, puis exécute deux tours Gateway CLI-backend sans conserver les variables d’environnement de clé API Anthropic. Cette voie d’abonnement désactive par défaut les sondes Claude MCP/tool et image parce que Claude achemine actuellement l’utilisation d’applications tierces via une facturation d’usage supplémentaire au lieu des limites normales du plan d’abonnement. -- Le smoke live du backend CLI exerce maintenant le même flux bout en bout pour Claude, Codex et Gemini : tour texte, tour de classification d’image, puis appel d’outil MCP `cron` vérifié via la CLI Gateway. -- Le smoke par défaut de Claude modifie aussi la session de Sonnet vers Opus et vérifie que la session reprise se souvient toujours d’une note antérieure. +- Il exécute le smoke live du backend CLI à l’intérieur de l’image Docker du dépôt en tant qu’utilisateur non root `node`. +- Il résout les métadonnées de smoke CLI à partir de l’extension propriétaire, puis installe le paquet CLI Linux correspondant (`@anthropic-ai/claude-code`, `@openai/codex` ou `@google/gemini-cli`) dans un préfixe inscriptible mis en cache sous `OPENCLAW_DOCKER_CLI_TOOLS_DIR` (par défaut : `~/.cache/openclaw/docker-cli-tools`). +- `pnpm test:docker:live-cli-backend:claude-subscription` nécessite une authentification OAuth portable Claude Code subscription via soit `~/.claude/.credentials.json` avec `claudeAiOauth.subscriptionType`, soit `CLAUDE_CODE_OAUTH_TOKEN` depuis `claude setup-token`. Il prouve d’abord un `claude -p` direct dans Docker, puis exécute deux tours Gateway CLI-backend sans conserver les variables d’environnement de clé API Anthropic. Cette voie subscription désactive par défaut l’outil Claude MCP et les sondes image, car Claude facture actuellement l’usage des applications tierces via une facturation d’usage supplémentaire plutôt que via les limites normales du plan d’abonnement. +- Le smoke live du backend CLI exerce désormais le même flux end-to-end pour Claude, Codex et Gemini : tour texte, tour de classification d’image, puis appel de l’outil MCP `cron` vérifié via le CLI Gateway. +- Le smoke par défaut de Claude modifie aussi la session de Sonnet à Opus et vérifie que la session reprise se souvient toujours d’une note antérieure. -## Live : smoke de liaison ACP (`/acp spawn ... --bind here`) +## Live : smoke d’attachement ACP (`/acp spawn ... --bind here`) - Test : `src/gateway/gateway-acp-bind.live.test.ts` -- Objectif : valider le véritable flux de liaison de conversation ACP avec un agent ACP en direct : +- Objectif : valider le vrai flux d’attachement de conversation ACP avec un agent ACP live : - envoyer `/acp spawn --bind here` - - lier sur place une conversation synthétique de canal de messages + - attacher en place une conversation synthétique de canal de messages - envoyer un suivi normal sur cette même conversation - - vérifier que le suivi arrive dans la transcription de session ACP liée -- Activer : + - vérifier que le suivi arrive dans la transcription de session ACP attachée +- Activation : - `pnpm test:live src/gateway/gateway-acp-bind.live.test.ts` - `OPENCLAW_LIVE_ACP_BIND=1` - Valeurs par défaut : - Agents ACP dans Docker : `claude,codex,gemini` - Agent ACP pour `pnpm test:live ...` direct : `claude` - - Canal synthétique : contexte de conversation de type DM Slack + - Canal synthétique : contexte de conversation de type message privé Slack - Backend ACP : `acpx` - Remplacements : - `OPENCLAW_LIVE_ACP_BIND_AGENT=claude` @@ -543,7 +550,7 @@ Recette Docker : pnpm test:docker:live-acp-bind ``` -Recettes Docker à agent unique : +Recettes Docker pour un seul agent : ```bash pnpm test:docker:live-acp-bind:claude @@ -554,31 +561,31 @@ pnpm test:docker:live-acp-bind:gemini Remarques Docker : - L’exécuteur Docker se trouve dans `scripts/test-live-acp-bind-docker.sh`. -- Par défaut, il exécute le smoke de liaison ACP sur tous les agents CLI live pris en charge en séquence : `claude`, `codex`, puis `gemini`. +- Par défaut, il exécute le smoke d’attachement ACP sur tous les agents CLI live pris en charge en séquence : `claude`, `codex`, puis `gemini`. - Utilisez `OPENCLAW_LIVE_ACP_BIND_AGENTS=claude`, `OPENCLAW_LIVE_ACP_BIND_AGENTS=codex` ou `OPENCLAW_LIVE_ACP_BIND_AGENTS=gemini` pour restreindre la matrice. -- Il charge `~/.profile`, prépare dans le conteneur le matériel d’authentification CLI correspondant, installe `acpx` dans un préfixe npm inscriptible, puis installe la CLI live demandée (`@anthropic-ai/claude-code`, `@openai/codex` ou `@google/gemini-cli`) si elle est absente. -- Dans Docker, l’exécuteur définit `OPENCLAW_LIVE_ACP_BIND_ACPX_COMMAND=$HOME/.npm-global/bin/acpx` afin que acpx conserve les variables d’environnement fournisseur du profil chargé disponibles pour la CLI harnais enfant. +- Il charge `~/.profile`, prépare dans le conteneur le matériel d’authentification CLI correspondant, installe `acpx` dans un préfixe npm inscriptible, puis installe le CLI live demandé (`@anthropic-ai/claude-code`, `@openai/codex` ou `@google/gemini-cli`) s’il manque. +- À l’intérieur de Docker, l’exécuteur définit `OPENCLAW_LIVE_ACP_BIND_ACPX_COMMAND=$HOME/.npm-global/bin/acpx` afin qu’acpx conserve disponibles pour le CLI harnais enfant les variables d’environnement du fournisseur issues du profil chargé. ## Live : smoke du harnais app-server Codex -- Objectif : valider le harnais Codex appartenant au Plugin via la méthode - `agent` Gateway normale : - - charger le Plugin groupé `codex` +- Objectif : valider le harnais Codex propriétaire du Plugin via la méthode + `agent` normale de Gateway : + - charger le Plugin `codex` intégré - sélectionner `OPENCLAW_AGENT_RUNTIME=codex` - - envoyer un premier tour d’agent Gateway vers `codex/gpt-5.4` - - envoyer un second tour à la même session OpenClaw et vérifier que le fil app-server - peut reprendre + - envoyer un premier tour d’agent Gateway à `codex/gpt-5.4` + - envoyer un second tour à la même session OpenClaw et vérifier que le thread + app-server peut reprendre - exécuter `/codex status` et `/codex models` via ce même chemin de commande Gateway - Test : `src/gateway/gateway-codex-harness.live.test.ts` -- Activer : `OPENCLAW_LIVE_CODEX_HARNESS=1` +- Activation : `OPENCLAW_LIVE_CODEX_HARNESS=1` - Modèle par défaut : `codex/gpt-5.4` - Sonde image facultative : `OPENCLAW_LIVE_CODEX_HARNESS_IMAGE_PROBE=1` -- Sonde MCP/tool facultative : `OPENCLAW_LIVE_CODEX_HARNESS_MCP_PROBE=1` +- Sonde MCP/outil facultative : `OPENCLAW_LIVE_CODEX_HARNESS_MCP_PROBE=1` - Le smoke définit `OPENCLAW_AGENT_HARNESS_FALLBACK=none` afin qu’un harnais Codex - cassé ne puisse pas réussir en basculant silencieusement vers PI. -- Authentification : `OPENAI_API_KEY` depuis le shell/profil, plus copie facultative - de `~/.codex/auth.json` et `~/.codex/config.toml` + cassé ne puisse pas réussir en retombant silencieusement sur PI. +- Authentification : `OPENAI_API_KEY` depuis le shell/profil, plus éventuellement + `~/.codex/auth.json` et `~/.codex/config.toml` copiés Recette locale : @@ -602,25 +609,26 @@ Remarques Docker : - L’exécuteur Docker se trouve dans `scripts/test-live-codex-harness-docker.sh`. - Il charge le `~/.profile` monté, transmet `OPENAI_API_KEY`, copie les fichiers - d’authentification de la CLI Codex lorsqu’ils sont présents, installe `@openai/codex` dans un préfixe npm - monté et inscriptible, prépare l’arborescence source, puis exécute uniquement le test live du harnais Codex. -- Docker active par défaut les sondes image et MCP/tool. Définissez + d’authentification du CLI Codex lorsqu’ils sont présents, installe `@openai/codex` + dans un préfixe npm monté et inscriptible, prépare l’arborescence source, puis n’exécute que le test live du harnais Codex. +- Docker active par défaut les sondes image et MCP/outil. Définissez `OPENCLAW_LIVE_CODEX_HARNESS_IMAGE_PROBE=0` ou `OPENCLAW_LIVE_CODEX_HARNESS_MCP_PROBE=0` lorsque vous avez besoin d’une exécution de débogage plus restreinte. -- Docker exporte aussi `OPENCLAW_AGENT_HARNESS_FALLBACK=none`, conformément à la configuration du test live afin que le repli `openai-codex/*` ou PI ne puisse pas masquer une - régression du harnais Codex. +- Docker exporte aussi `OPENCLAW_AGENT_HARNESS_FALLBACK=none`, conformément à la configuration du + test live, afin qu’un repli sur `openai-codex/*` ou PI ne puisse pas masquer une régression + du harnais Codex. ### Recettes live recommandées -Les listes d’autorisation restreintes et explicites sont les plus rapides et les moins instables : +Des listes d’autorisation étroites et explicites sont plus rapides et moins fragiles : -- Modèle unique, direct (sans Gateway) : +- Un seul modèle, direct (sans gateway) : - `OPENCLAW_LIVE_MODELS="openai/gpt-5.4" pnpm test:live src/agents/models.profiles.live.test.ts` -- Modèle unique, smoke Gateway : +- Un seul modèle, smoke Gateway : - `OPENCLAW_LIVE_GATEWAY_MODELS="openai/gpt-5.4" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts` -- Appel d’outils sur plusieurs fournisseurs : +- Appel d’outil sur plusieurs fournisseurs : - `OPENCLAW_LIVE_GATEWAY_MODELS="openai/gpt-5.4,anthropic/claude-opus-4-6,google/gemini-3-flash-preview,zai/glm-4.7,minimax/MiniMax-M2.7" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts` - Focus Google (clé API Gemini + Antigravity) : @@ -631,18 +639,18 @@ Remarques : - `google/...` utilise l’API Gemini (clé API). - `google-antigravity/...` utilise le pont OAuth Antigravity (point de terminaison d’agent de type Cloud Code Assist). -- `google-gemini-cli/...` utilise la CLI Gemini locale sur votre machine (authentification distincte + particularités d’outillage). +- `google-gemini-cli/...` utilise le CLI Gemini local sur votre machine (authentification distincte + particularités d’outillage). - API Gemini vs CLI Gemini : - - API : OpenClaw appelle l’API Gemini hébergée de Google via HTTP (clé API / authentification de profil) ; c’est ce que la plupart des utilisateurs entendent par « Gemini ». - - CLI : OpenClaw exécute un binaire local `gemini` ; il dispose de sa propre authentification et peut se comporter différemment (streaming/prise en charge des outils/décalage de version). + - API : OpenClaw appelle l’API Gemini hébergée par Google via HTTP (clé API / authentification de profil) ; c’est ce que la plupart des utilisateurs veulent dire par « Gemini ». + - CLI : OpenClaw exécute un binaire local `gemini` ; il a sa propre authentification et peut se comporter différemment (streaming/prise en charge des outils/décalage de version). ## Live : matrice de modèles (ce que nous couvrons) Il n’existe pas de « liste de modèles CI » fixe (live est opt-in), mais voici les modèles **recommandés** à couvrir régulièrement sur une machine de développement avec des clés. -### Ensemble de smoke moderne (appel d’outils + image) +### Ensemble de smoke moderne (appel d’outil + image) -Il s’agit de l’exécution « modèles courants » que nous nous attendons à maintenir fonctionnelle : +Il s’agit de l’exécution des « modèles courants » que nous nous attendons à voir continuer de fonctionner : - OpenAI (hors Codex) : `openai/gpt-5.4` (facultatif : `openai/gpt-5.4-mini`) - OpenAI Codex : `openai-codex/gpt-5.4` @@ -652,12 +660,12 @@ Il s’agit de l’exécution « modèles courants » que nous nous attendons - Z.AI (GLM) : `zai/glm-4.7` - MiniMax : `minimax/MiniMax-M2.7` -Exécuter le smoke Gateway avec outils + image : +Exécutez le smoke Gateway avec outils + image : `OPENCLAW_LIVE_GATEWAY_MODELS="openai/gpt-5.4,openai-codex/gpt-5.4,anthropic/claude-opus-4-6,google/gemini-3.1-pro-preview,google/gemini-3-flash-preview,google-antigravity/claude-opus-4-6-thinking,google-antigravity/gemini-3-flash,zai/glm-4.7,minimax/MiniMax-M2.7" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts` -### Base de référence : appel d’outils (Read + Exec facultatif) +### Base : appel d’outil (Read + Exec facultatif) -Choisissez au moins un modèle par famille de fournisseurs : +Choisissez-en au moins un par famille de fournisseurs : - OpenAI : `openai/gpt-5.4` (ou `openai/gpt-5.4-mini`) - Anthropic : `anthropic/claude-opus-4-6` (ou `anthropic/claude-sonnet-4-6`) @@ -665,12 +673,12 @@ Choisissez au moins un modèle par famille de fournisseurs : - Z.AI (GLM) : `zai/glm-4.7` - MiniMax : `minimax/MiniMax-M2.7` -Couverture supplémentaire facultative (utile, mais non indispensable) : +Couverture supplémentaire facultative (appréciable) : - xAI : `xai/grok-4` (ou la dernière version disponible) -- Mistral : `mistral/`… (choisissez un modèle « tools » activé) +- Mistral : `mistral/`… (choisissez un modèle compatible « tools » que vous avez activé) - Cerebras : `cerebras/`… (si vous y avez accès) -- LM Studio : `lmstudio/`… (local ; l’appel d’outils dépend du mode API) +- LM Studio : `lmstudio/`… (local ; l’appel d’outil dépend du mode API) ### Vision : envoi d’image (pièce jointe → message multimodal) @@ -678,51 +686,51 @@ Incluez au moins un modèle compatible image dans `OPENCLAW_LIVE_GATEWAY_MODELS` ### Agrégateurs / passerelles alternatives -Si vous avez des clés activées, nous prenons aussi en charge les tests via : +Si vous avez activé des clés, nous prenons aussi en charge les tests via : - OpenRouter : `openrouter/...` (des centaines de modèles ; utilisez `openclaw models scan` pour trouver des candidats compatibles outils+image) - OpenCode : `opencode/...` pour Zen et `opencode-go/...` pour Go (authentification via `OPENCODE_API_KEY` / `OPENCODE_ZEN_API_KEY`) -Davantage de fournisseurs peuvent être inclus dans la matrice live (si vous avez les identifiants/la configuration) : +D’autres fournisseurs que vous pouvez inclure dans la matrice live (si vous avez les identifiants/la configuration) : - Intégrés : `openai`, `openai-codex`, `anthropic`, `google`, `google-vertex`, `google-antigravity`, `google-gemini-cli`, `zai`, `openrouter`, `opencode`, `opencode-go`, `xai`, `groq`, `cerebras`, `mistral`, `github-copilot` - Via `models.providers` (points de terminaison personnalisés) : `minimax` (cloud/API), plus tout proxy compatible OpenAI/Anthropic (LM Studio, vLLM, LiteLLM, etc.) Astuce : n’essayez pas de coder en dur « tous les modèles » dans la documentation. La liste faisant autorité est celle que `discoverModels(...)` renvoie sur votre machine + les clés disponibles. -## Identifiants (ne jamais valider) +## Identifiants (ne jamais commit) -Les tests live découvrent les identifiants de la même façon que la CLI. Conséquences pratiques : +Les tests live découvrent les identifiants de la même manière que le CLI. Conséquences pratiques : -- Si la CLI fonctionne, les tests live devraient trouver les mêmes clés. -- Si un test live indique « aucun identifiant », déboguez-le de la même façon que `openclaw models list` / la sélection de modèle. +- Si le CLI fonctionne, les tests live devraient trouver les mêmes clés. +- Si un test live indique « pas d’identifiants », déboguez-le de la même manière que `openclaw models list` / la sélection de modèle. -- Profils d’authentification par agent : `~/.openclaw/agents//agent/auth-profiles.json` (c’est ce que signifient les « clés de profil » dans les tests live) +- Profils d’authentification par agent : `~/.openclaw/agents//agent/auth-profiles.json` (c’est ce que « clés de profil » signifie dans les tests live) - Configuration : `~/.openclaw/openclaw.json` (ou `OPENCLAW_CONFIG_PATH`) -- Répertoire d’état hérité : `~/.openclaw/credentials/` (copié dans le home live préparé lorsqu’il est présent, mais ce n’est pas le magasin principal des clés de profil) -- Les exécutions locales live copient par défaut la configuration active, les fichiers `auth-profiles.json` par agent, `credentials/` hérité, ainsi que les répertoires d’authentification CLI externes pris en charge dans un home de test temporaire ; les homes live préparés ignorent `workspace/` et `sandboxes/`, et les remplacements de chemin `agents.*.workspace` / `agentDir` sont supprimés afin que les sondes restent hors de votre véritable espace de travail hôte. +- Ancien répertoire d’état : `~/.openclaw/credentials/` (copié dans le home live préparé lorsqu’il est présent, mais pas dans le magasin principal de clés de profil) +- Les exécutions locales live copient par défaut la configuration active, les fichiers `auth-profiles.json` par agent, l’ancien `credentials/` et les répertoires d’authentification CLI externes pris en charge dans un home de test temporaire ; les homes live préparés ignorent `workspace/` et `sandboxes/`, et les remplacements de chemin `agents.*.workspace` / `agentDir` sont supprimés afin que les sondes n’utilisent pas votre véritable espace de travail hôte. Si vous voulez vous appuyer sur des clés d’environnement (par exemple exportées dans votre `~/.profile`), exécutez les tests locaux après `source ~/.profile`, ou utilisez les exécuteurs Docker ci-dessous (ils peuvent monter `~/.profile` dans le conteneur). ## Live Deepgram (transcription audio) - Test : `src/media-understanding/providers/deepgram/audio.live.test.ts` -- Activer : `DEEPGRAM_API_KEY=... DEEPGRAM_LIVE_TEST=1 pnpm test:live src/media-understanding/providers/deepgram/audio.live.test.ts` +- Activation : `DEEPGRAM_API_KEY=... DEEPGRAM_LIVE_TEST=1 pnpm test:live src/media-understanding/providers/deepgram/audio.live.test.ts` -## Live plan de codage BytePlus +## Live BytePlus coding plan - Test : `src/agents/byteplus.live.test.ts` -- Activer : `BYTEPLUS_API_KEY=... BYTEPLUS_LIVE_TEST=1 pnpm test:live src/agents/byteplus.live.test.ts` -- Remplacement de modèle facultatif : `BYTEPLUS_CODING_MODEL=ark-code-latest` +- Activation : `BYTEPLUS_API_KEY=... BYTEPLUS_LIVE_TEST=1 pnpm test:live src/agents/byteplus.live.test.ts` +- Remplacement facultatif du modèle : `BYTEPLUS_CODING_MODEL=ark-code-latest` ## Live média de workflow ComfyUI - Test : `extensions/comfy/comfy.live.test.ts` -- Activer : `OPENCLAW_LIVE_TEST=1 COMFY_LIVE_TEST=1 pnpm test:live -- extensions/comfy/comfy.live.test.ts` +- Activation : `OPENCLAW_LIVE_TEST=1 COMFY_LIVE_TEST=1 pnpm test:live -- extensions/comfy/comfy.live.test.ts` - Portée : - - Exerce les chemins groupés comfy d’image, de vidéo et `music_generate` - - Ignore chaque capacité sauf si `models.providers.comfy.` est configuré - - Utile après une modification de la soumission de workflow comfy, du polling, des téléchargements ou de l’enregistrement du Plugin + - Exerce les chemins image, vidéo et `music_generate` du comfy intégré + - Ignore chaque capacité à moins que `models.providers.comfy.` soit configuré + - Utile après avoir modifié l’envoi de workflow comfy, le polling, les téléchargements ou l’enregistrement du Plugin ## Live génération d’images @@ -731,15 +739,15 @@ Si vous voulez vous appuyer sur des clés d’environnement (par exemple export - Harnais : `pnpm test:live:media image` - Portée : - Énumère chaque Plugin fournisseur de génération d’images enregistré - - Charge les variables d’environnement fournisseur manquantes depuis votre shell de connexion (`~/.profile`) avant la sonde - - Utilise par défaut les clés API live/env avant les profils d’authentification stockés, afin que des clés de test obsolètes dans `auth-profiles.json` ne masquent pas les véritables identifiants du shell + - Charge les variables d’environnement de fournisseur manquantes depuis votre shell de connexion (`~/.profile`) avant les sondes + - Utilise par défaut les clés API live/env avant les profils d’authentification stockés, afin que des clés de test obsolètes dans `auth-profiles.json` ne masquent pas de vrais identifiants du shell - Ignore les fournisseurs sans authentification/profil/modèle utilisable - - Exécute les variantes standards de génération d’images via la capacité d’exécution partagée : + - Exécute les variantes standard de génération d’images via la capacité runtime partagée : - `google:flash-generate` - `google:pro-generate` - `google:pro-edit` - `openai:default-generate` -- Fournisseurs groupés actuellement couverts : +- Fournisseurs intégrés actuellement couverts : - `openai` - `google` - Restriction facultative : @@ -747,21 +755,21 @@ Si vous voulez vous appuyer sur des clés d’environnement (par exemple export - `OPENCLAW_LIVE_IMAGE_GENERATION_MODELS="openai/gpt-image-1,google/gemini-3.1-flash-image-preview"` - `OPENCLAW_LIVE_IMAGE_GENERATION_CASES="google:flash-generate,google:pro-edit"` - Comportement d’authentification facultatif : - - `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` pour imposer l’authentification par magasin de profils et ignorer les remplacements uniquement via env + - `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` pour forcer l’authentification via magasin de profils et ignorer les remplacements uniquement fournis par l’environnement -## Live génération musicale +## Live génération de musique - Test : `extensions/music-generation-providers.live.test.ts` -- Activer : `OPENCLAW_LIVE_TEST=1 pnpm test:live -- extensions/music-generation-providers.live.test.ts` +- Activation : `OPENCLAW_LIVE_TEST=1 pnpm test:live -- extensions/music-generation-providers.live.test.ts` - Harnais : `pnpm test:live:media music` - Portée : - - Exerce le chemin partagé groupé des fournisseurs de génération musicale + - Exerce le chemin partagé intégré des fournisseurs de génération de musique - Couvre actuellement Google et MiniMax - - Charge les variables d’environnement fournisseur depuis votre shell de connexion (`~/.profile`) avant la sonde - - Utilise par défaut les clés API live/env avant les profils d’authentification stockés, afin que des clés de test obsolètes dans `auth-profiles.json` ne masquent pas les véritables identifiants du shell + - Charge les variables d’environnement de fournisseur depuis votre shell de connexion (`~/.profile`) avant les sondes + - Utilise par défaut les clés API live/env avant les profils d’authentification stockés, afin que des clés de test obsolètes dans `auth-profiles.json` ne masquent pas de vrais identifiants du shell - Ignore les fournisseurs sans authentification/profil/modèle utilisable - - Exécute les deux modes d’exécution déclarés lorsqu’ils sont disponibles : - - `generate` avec entrée fondée uniquement sur une invite + - Exécute les deux modes runtime déclarés lorsqu’ils sont disponibles : + - `generate` avec entrée basée uniquement sur prompt - `edit` lorsque le fournisseur déclare `capabilities.edit.enabled` - Couverture actuelle de la voie partagée : - `google` : `generate`, `edit` @@ -771,46 +779,50 @@ Si vous voulez vous appuyer sur des clés d’environnement (par exemple export - `OPENCLAW_LIVE_MUSIC_GENERATION_PROVIDERS="google,minimax"` - `OPENCLAW_LIVE_MUSIC_GENERATION_MODELS="google/lyria-3-clip-preview,minimax/music-2.5+"` - Comportement d’authentification facultatif : - - `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` pour imposer l’authentification par magasin de profils et ignorer les remplacements uniquement via env + - `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` pour forcer l’authentification via magasin de profils et ignorer les remplacements uniquement fournis par l’environnement -## Live génération vidéo +## Live génération de vidéos - Test : `extensions/video-generation-providers.live.test.ts` -- Activer : `OPENCLAW_LIVE_TEST=1 pnpm test:live -- extensions/video-generation-providers.live.test.ts` +- Activation : `OPENCLAW_LIVE_TEST=1 pnpm test:live -- extensions/video-generation-providers.live.test.ts` - Harnais : `pnpm test:live:media video` - Portée : - - Exerce le chemin partagé groupé des fournisseurs de génération vidéo - - Charge les variables d’environnement fournisseur depuis votre shell de connexion (`~/.profile`) avant la sonde - - Utilise par défaut les clés API live/env avant les profils d’authentification stockés, afin que des clés de test obsolètes dans `auth-profiles.json` ne masquent pas les véritables identifiants du shell + - Exerce le chemin partagé intégré des fournisseurs de génération de vidéos + - Utilise par défaut le chemin de smoke sûr pour la release : fournisseurs hors FAL, une requête text-to-video par fournisseur, prompt lobster d’une seconde, et une limite d’opération par fournisseur issue de `OPENCLAW_LIVE_VIDEO_GENERATION_TIMEOUT_MS` (`180000` par défaut) + - Ignore FAL par défaut, car la latence de file d’attente côté fournisseur peut dominer le temps de release ; passez `--video-providers fal` ou `OPENCLAW_LIVE_VIDEO_GENERATION_PROVIDERS="fal"` pour l’exécuter explicitement + - Charge les variables d’environnement de fournisseur depuis votre shell de connexion (`~/.profile`) avant les sondes + - Utilise par défaut les clés API live/env avant les profils d’authentification stockés, afin que des clés de test obsolètes dans `auth-profiles.json` ne masquent pas de vrais identifiants du shell - Ignore les fournisseurs sans authentification/profil/modèle utilisable - - Exécute les deux modes d’exécution déclarés lorsqu’ils sont disponibles : - - `generate` avec entrée fondée uniquement sur une invite - - `imageToVideo` lorsque le fournisseur déclare `capabilities.imageToVideo.enabled` et que le fournisseur/modèle sélectionné accepte une entrée image locale fondée sur tampon dans le balayage partagé - - `videoToVideo` lorsque le fournisseur déclare `capabilities.videoToVideo.enabled` et que le fournisseur/modèle sélectionné accepte une entrée vidéo locale fondée sur tampon dans le balayage partagé + - N’exécute que `generate` par défaut + - Définissez `OPENCLAW_LIVE_VIDEO_GENERATION_FULL_MODES=1` pour exécuter aussi les modes de transformation déclarés lorsqu’ils sont disponibles : + - `imageToVideo` lorsque le fournisseur déclare `capabilities.imageToVideo.enabled` et que le fournisseur/modèle sélectionné accepte une entrée image locale basée sur buffer dans le balayage partagé + - `videoToVideo` lorsque le fournisseur déclare `capabilities.videoToVideo.enabled` et que le fournisseur/modèle sélectionné accepte une entrée vidéo locale basée sur buffer dans le balayage partagé - Fournisseurs `imageToVideo` actuellement déclarés mais ignorés dans le balayage partagé : - - `vydra` car le `veo3` groupé est uniquement textuel et le `kling` groupé nécessite une URL d’image distante - - Couverture spécifique au fournisseur Vydra : + - `vydra`, car le `veo3` intégré est uniquement textuel et le `kling` intégré nécessite une URL d’image distante + - Couverture Vydra spécifique au fournisseur : - `OPENCLAW_LIVE_TEST=1 OPENCLAW_LIVE_VYDRA_VIDEO=1 pnpm test:live -- extensions/vydra/vydra.live.test.ts` - - ce fichier exécute `veo3` en texte-vers-vidéo plus une voie `kling` qui utilise par défaut un fixture d’URL d’image distante + - ce fichier exécute `veo3` text-to-video ainsi qu’une voie `kling` qui utilise par défaut une fixture d’URL d’image distante - Couverture live actuelle de `videoToVideo` : - `runway` uniquement lorsque le modèle sélectionné est `runway/gen4_aleph` - Fournisseurs `videoToVideo` actuellement déclarés mais ignorés dans le balayage partagé : - - `alibaba`, `qwen`, `xai` car ces chemins exigent actuellement des URL de référence distantes `http(s)` / MP4 - - `google` car la voie Gemini/Veo partagée actuelle utilise une entrée locale fondée sur tampon et ce chemin n’est pas accepté dans le balayage partagé - - `openai` car la voie partagée actuelle ne garantit pas l’accès spécifique à l’organisation pour l’inpainting/remix vidéo + - `alibaba`, `qwen`, `xai`, car ces chemins nécessitent actuellement des URL de référence distantes `http(s)` / MP4 + - `google`, car la voie Gemini/Veo partagée actuelle utilise une entrée locale basée sur buffer et ce chemin n’est pas accepté dans le balayage partagé + - `openai`, car la voie partagée actuelle ne garantit pas l’accès spécifique à l’organisation pour l’inpaint/remix vidéo - Restriction facultative : - `OPENCLAW_LIVE_VIDEO_GENERATION_PROVIDERS="google,openai,runway"` - `OPENCLAW_LIVE_VIDEO_GENERATION_MODELS="google/veo-3.1-fast-generate-preview,openai/sora-2,runway/gen4_aleph"` + - `OPENCLAW_LIVE_VIDEO_GENERATION_SKIP_PROVIDERS=""` pour inclure tous les fournisseurs dans le balayage par défaut, y compris FAL + - `OPENCLAW_LIVE_VIDEO_GENERATION_TIMEOUT_MS=60000` pour réduire la limite d’opération de chaque fournisseur lors d’une exécution smoke agressive - Comportement d’authentification facultatif : - - `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` pour imposer l’authentification par magasin de profils et ignorer les remplacements uniquement via env + - `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` pour forcer l’authentification via magasin de profils et ignorer les remplacements uniquement fournis par l’environnement -## Harnais média live +## Harnais live média - Commande : `pnpm test:live:media` - Objectif : - Exécute les suites live partagées d’image, de musique et de vidéo via un point d’entrée natif au dépôt - - Charge automatiquement les variables d’environnement fournisseur manquantes depuis `~/.profile` - - Restreint automatiquement chaque suite par défaut aux fournisseurs disposant actuellement d’une authentification utilisable + - Charge automatiquement les variables d’environnement de fournisseur manquantes depuis `~/.profile` + - Restreint automatiquement chaque suite, par défaut, aux fournisseurs qui disposent actuellement d’une authentification exploitable - Réutilise `scripts/test-live.mjs`, afin que le comportement Heartbeat et le mode silencieux restent cohérents - Exemples : - `pnpm test:live:media` @@ -820,68 +832,68 @@ Si vous voulez vous appuyer sur des clés d’environnement (par exemple export ## Exécuteurs Docker (vérifications facultatives « fonctionne sous Linux ») -Ces exécuteurs Docker se divisent en deux catégories : +Ces exécuteurs Docker se répartissent en deux catégories : -- Exécuteurs de modèles live : `test:docker:live-models` et `test:docker:live-gateway` n’exécutent que leur fichier live à clés de profil correspondant dans l’image Docker du dépôt (`src/agents/models.profiles.live.test.ts` et `src/gateway/gateway-models.profiles.live.test.ts`), en montant votre répertoire de configuration local et votre espace de travail (et en chargeant `~/.profile` s’il est monté). Les points d’entrée locaux correspondants sont `test:live:models-profiles` et `test:live:gateway-profiles`. -- Les exécuteurs live Docker utilisent par défaut un plafond de smoke plus réduit afin qu’un balayage Docker complet reste praticable : +- Exécuteurs de modèles live : `test:docker:live-models` et `test:docker:live-gateway` n’exécutent que leur fichier live à clés de profil correspondant à l’intérieur de l’image Docker du dépôt (`src/agents/models.profiles.live.test.ts` et `src/gateway/gateway-models.profiles.live.test.ts`), en montant votre répertoire de configuration local et votre espace de travail (et en chargeant `~/.profile` s’il est monté). Les points d’entrée locaux correspondants sont `test:live:models-profiles` et `test:live:gateway-profiles`. +- Les exécuteurs live Docker utilisent par défaut une limite de smoke plus petite afin qu’un balayage Docker complet reste praticable : `test:docker:live-models` utilise par défaut `OPENCLAW_LIVE_MAX_MODELS=12`, et `test:docker:live-gateway` utilise par défaut `OPENCLAW_LIVE_GATEWAY_SMOKE=1`, `OPENCLAW_LIVE_GATEWAY_MAX_MODELS=8`, `OPENCLAW_LIVE_GATEWAY_STEP_TIMEOUT_MS=45000`, et `OPENCLAW_LIVE_GATEWAY_MODEL_TIMEOUT_MS=90000`. Remplacez ces variables d’environnement lorsque vous - souhaitez explicitement un balayage exhaustif plus large. -- `test:docker:all` construit une seule fois l’image Docker live via `test:docker:live-build`, puis la réutilise pour les deux voies Docker live. -- Exécuteurs de smoke de conteneur : `test:docker:openwebui`, `test:docker:onboard`, `test:docker:gateway-network`, `test:docker:mcp-channels` et `test:docker:plugins` démarrent un ou plusieurs vrais conteneurs et vérifient des chemins d’intégration de plus haut niveau. + voulez explicitement le balayage exhaustif plus large. +- `test:docker:all` construit une fois l’image live Docker via `test:docker:live-build`, puis la réutilise pour les deux voies live Docker. +- Exécuteurs de smoke de conteneur : `test:docker:openwebui`, `test:docker:onboard`, `test:docker:gateway-network`, `test:docker:mcp-channels` et `test:docker:plugins` démarrent un ou plusieurs conteneurs réels et vérifient des chemins d’intégration de plus haut niveau. -Les exécuteurs Docker de modèles live montent aussi uniquement les homes d’authentification CLI nécessaires (ou tous ceux pris en charge lorsque l’exécution n’est pas restreinte), puis les copient dans le home du conteneur avant l’exécution afin que l’OAuth des CLI externes puisse rafraîchir les jetons sans modifier le magasin d’authentification de l’hôte : +Les exécuteurs Docker de modèles live montent aussi en bind uniquement les homes d’authentification CLI nécessaires (ou tous ceux pris en charge lorsque l’exécution n’est pas restreinte), puis les copient dans le home du conteneur avant l’exécution afin que l’OAuth CLI externe puisse actualiser les jetons sans modifier le magasin d’authentification de l’hôte : - Modèles directs : `pnpm test:docker:live-models` (script : `scripts/test-live-models-docker.sh`) -- Smoke de liaison ACP : `pnpm test:docker:live-acp-bind` (script : `scripts/test-live-acp-bind-docker.sh`) +- Smoke d’attachement ACP : `pnpm test:docker:live-acp-bind` (script : `scripts/test-live-acp-bind-docker.sh`) - Smoke du backend CLI : `pnpm test:docker:live-cli-backend` (script : `scripts/test-live-cli-backend-docker.sh`) - Smoke du harnais app-server Codex : `pnpm test:docker:live-codex-harness` (script : `scripts/test-live-codex-harness-docker.sh`) -- Gateway + agent de développement : `pnpm test:docker:live-gateway` (script : `scripts/test-live-gateway-models-docker.sh`) +- Gateway + agent dev : `pnpm test:docker:live-gateway` (script : `scripts/test-live-gateway-models-docker.sh`) - Smoke live Open WebUI : `pnpm test:docker:openwebui` (script : `scripts/e2e/openwebui-docker.sh`) - Assistant d’onboarding (TTY, échafaudage complet) : `pnpm test:docker:onboard` (script : `scripts/e2e/onboard-docker.sh`) -- Réseau Gateway (deux conteneurs, auth WS + état de santé) : `pnpm test:docker:gateway-network` (script : `scripts/e2e/gateway-network-docker.sh`) -- Pont de canal MCP (Gateway préremplie + pont stdio + smoke brut de trame de notification Claude) : `pnpm test:docker:mcp-channels` (script : `scripts/e2e/mcp-channels-docker.sh`) +- Réseau Gateway (deux conteneurs, authentification WS + santé) : `pnpm test:docker:gateway-network` (script : `scripts/e2e/gateway-network-docker.sh`) +- Pont de canal MCP (Gateway initialisée + pont stdio + smoke brut des frames de notification Claude) : `pnpm test:docker:mcp-channels` (script : `scripts/e2e/mcp-channels-docker.sh`) - Plugins (smoke d’installation + alias `/plugin` + sémantique de redémarrage du bundle Claude) : `pnpm test:docker:plugins` (script : `scripts/e2e/plugins-docker.sh`) -Les exécuteurs Docker de modèles live montent aussi le checkout courant en lecture seule et -le préparent dans un répertoire de travail temporaire à l’intérieur du conteneur. Cela garde l’image -d’exécution légère tout en exécutant Vitest sur votre source/configuration locale exacte. -L’étape de préparation ignore les gros caches locaux et les sorties de build d’applications tels que -`.pnpm-store`, `.worktrees`, `__openclaw_vitest__`, et les répertoires de sortie locaux `.build` ou -Gradle afin que les exécutions live Docker ne passent pas des minutes à copier +Les exécuteurs Docker de modèles live montent aussi en bind le checkout actuel en lecture seule et +le préparent dans un répertoire de travail temporaire à l’intérieur du conteneur. Cela garde l’image runtime +légère tout en exécutant Vitest sur votre source/configuration locale exacte. +L’étape de préparation ignore les gros caches purement locaux et les sorties de build de l’application, telles que +`.pnpm-store`, `.worktrees`, `__openclaw_vitest__`, et les répertoires `.build` locaux à l’application ou les sorties +Gradle, afin que les exécutions live Docker ne passent pas des minutes à copier des artefacts spécifiques à la machine. Ils définissent aussi `OPENCLAW_SKIP_CHANNELS=1` afin que les sondes live Gateway ne démarrent pas -de vrais workers de canaux Telegram/Discord/etc. à l’intérieur du conteneur. -`test:docker:live-models` exécute toujours `pnpm test:live`, donc transmettez aussi +de vrais workers de canal Telegram/Discord/etc. à l’intérieur du conteneur. +`test:docker:live-models` exécute toujours `pnpm test:live`, donc faites aussi passer `OPENCLAW_LIVE_GATEWAY_*` lorsque vous devez restreindre ou exclure la couverture live Gateway de cette voie Docker. `test:docker:openwebui` est un smoke de compatibilité de plus haut niveau : il démarre un conteneur Gateway OpenClaw avec les points de terminaison HTTP compatibles OpenAI activés, -démarre un conteneur Open WebUI épinglé contre cette Gateway, se connecte via +démarre un conteneur Open WebUI épinglé sur cette Gateway, se connecte via Open WebUI, vérifie que `/api/models` expose `openclaw/default`, puis envoie une vraie requête de chat via le proxy `/api/chat/completions` d’Open WebUI. La première exécution peut être sensiblement plus lente, car Docker peut devoir récupérer l’image -Open WebUI et Open WebUI peut devoir terminer sa propre configuration de démarrage à froid. +Open WebUI et Open WebUI peut devoir terminer sa propre configuration à froid. Cette voie attend une clé de modèle live utilisable, et `OPENCLAW_PROFILE_FILE` -(`~/.profile` par défaut) est la manière principale de la fournir dans les exécutions conteneurisées. -Les exécutions réussies affichent une petite charge utile JSON comme `{ "ok": true, "model": +(`~/.profile` par défaut) est le moyen principal de la fournir dans les exécutions Docker. +Les exécutions réussies affichent une petite charge JSON telle que `{ "ok": true, "model": "openclaw/default", ... }`. -`test:docker:mcp-channels` est volontairement déterministe et n’a pas besoin d’un -vrai compte Telegram, Discord ou iMessage. Il démarre un conteneur Gateway -prérempli, lance un second conteneur qui exécute `openclaw mcp serve`, puis -vérifie la découverte des conversations routées, la lecture des transcriptions, les métadonnées de pièces jointes, -le comportement de la file d’événements en direct, le routage d’envoi sortant, et les notifications de canal + -de permissions de type Claude sur le vrai pont MCP stdio. La vérification des notifications -inspecte directement les trames MCP stdio brutes afin que le smoke valide ce que le -pont émet réellement, et non seulement ce qu’un SDK client spécifique expose en surface. +`test:docker:mcp-channels` est volontairement déterministe et ne nécessite pas +de vrai compte Telegram, Discord ou iMessage. Il démarre une +Gateway initialisée en conteneur, lance un second conteneur qui exécute `openclaw mcp serve`, puis +vérifie la découverte des conversations routées, la lecture des transcriptions, les métadonnées des pièces jointes, +le comportement de la file d’événements live, le routage des envois sortants, et les notifications de canal + +autorisation de type Claude sur le vrai pont stdio MCP. La vérification des notifications +inspecte directement les frames MCP stdio brutes afin que le smoke valide ce que le +pont émet réellement, et pas seulement ce qu’un SDK client particulier expose par hasard. -Smoke manuel ACP en langage naturel pour les fils (hors CI) : +Smoke manuel ACP en langage courant pour les fils (hors CI) : - `bun scripts/dev/discord-acp-plain-language-smoke.ts --channel ...` -- Conservez ce script pour les flux de régression/débogage. Il pourrait de nouveau être nécessaire pour valider le routage des fils ACP, donc ne le supprimez pas. +- Conservez ce script pour les workflows de régression/débogage. Il pourra être de nouveau nécessaire pour valider le routage des fils ACP, donc ne le supprimez pas. Variables d’environnement utiles : @@ -892,112 +904,112 @@ Variables d’environnement utiles : - Les répertoires/fichiers d’authentification CLI externes sous `$HOME` sont montés en lecture seule sous `/host-auth...`, puis copiés dans `/home/node/...` avant le démarrage des tests - Répertoires par défaut : `.minimax` - Fichiers par défaut : `~/.codex/auth.json`, `~/.codex/config.toml`, `.claude.json`, `~/.claude/.credentials.json`, `~/.claude/settings.json`, `~/.claude/settings.local.json` - - Les exécutions restreintes par fournisseur ne montent que les répertoires/fichiers nécessaires déduits depuis `OPENCLAW_LIVE_PROVIDERS` / `OPENCLAW_LIVE_GATEWAY_PROVIDERS` + - Les exécutions restreintes par fournisseur ne montent que les répertoires/fichiers nécessaires déduits de `OPENCLAW_LIVE_PROVIDERS` / `OPENCLAW_LIVE_GATEWAY_PROVIDERS` - Remplacement manuel avec `OPENCLAW_DOCKER_AUTH_DIRS=all`, `OPENCLAW_DOCKER_AUTH_DIRS=none`, ou une liste séparée par des virgules comme `OPENCLAW_DOCKER_AUTH_DIRS=.claude,.codex` - `OPENCLAW_LIVE_GATEWAY_MODELS=...` / `OPENCLAW_LIVE_MODELS=...` pour restreindre l’exécution - `OPENCLAW_LIVE_GATEWAY_PROVIDERS=...` / `OPENCLAW_LIVE_PROVIDERS=...` pour filtrer les fournisseurs dans le conteneur -- `OPENCLAW_SKIP_DOCKER_BUILD=1` pour réutiliser une image `openclaw:local-live` existante lors de réexécutions ne nécessitant pas de reconstruction -- `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` pour garantir que les identifiants proviennent du magasin de profils (et non de env) +- `OPENCLAW_SKIP_DOCKER_BUILD=1` pour réutiliser une image `openclaw:local-live` existante lors des réexécutions qui ne nécessitent pas de reconstruction +- `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` pour s’assurer que les identifiants proviennent du magasin de profils (et non de l’environnement) - `OPENCLAW_OPENWEBUI_MODEL=...` pour choisir le modèle exposé par la Gateway pour le smoke Open WebUI -- `OPENCLAW_OPENWEBUI_PROMPT=...` pour remplacer l’invite de vérification de nonce utilisée par le smoke Open WebUI +- `OPENCLAW_OPENWEBUI_PROMPT=...` pour remplacer le prompt de vérification du nonce utilisé par le smoke Open WebUI - `OPENWEBUI_IMAGE=...` pour remplacer la balise d’image Open WebUI épinglée -## Vérification de cohérence de la documentation +## Vérification de la documentation -Exécutez les vérifications de documentation après des modifications de docs : `pnpm check:docs`. +Exécutez les vérifications de documentation après des modifications de doc : `pnpm check:docs`. Exécutez la validation complète des ancres Mintlify lorsque vous avez aussi besoin de vérifier les titres dans la page : `pnpm docs:check-links:anchors`. ## Régression hors ligne (compatible CI) -Ce sont des régressions de « pipeline réel » sans vrais fournisseurs : +Il s’agit de régressions de « pipeline réel » sans vrais fournisseurs : -- Appel d’outils Gateway (mock OpenAI, vraie boucle Gateway + agent) : `src/gateway/gateway.test.ts` (cas : "runs a mock OpenAI tool call end-to-end via gateway agent loop") +- Appel d’outil Gateway (OpenAI simulé, vraie boucle gateway + agent) : `src/gateway/gateway.test.ts` (cas : "runs a mock OpenAI tool call end-to-end via gateway agent loop") - Assistant Gateway (WS `wizard.start`/`wizard.next`, écrit config + auth imposée) : `src/gateway/gateway.test.ts` (cas : "runs wizard over ws and writes auth token config") ## Évaluations de fiabilité d’agent (Skills) Nous avons déjà quelques tests compatibles CI qui se comportent comme des « évaluations de fiabilité d’agent » : -- Appel d’outils simulé via la vraie boucle Gateway + agent (`src/gateway/gateway.test.ts`). -- Flux d’assistant bout en bout qui valident le câblage de session et les effets de configuration (`src/gateway/gateway.test.ts`). +- Appel d’outil simulé via la vraie boucle gateway + agent (`src/gateway/gateway.test.ts`). +- Flux end-to-end de l’assistant qui valident le câblage des sessions et les effets de configuration (`src/gateway/gateway.test.ts`). Ce qui manque encore pour les Skills (voir [Skills](/fr/tools/skills)) : -- **Prise de décision :** lorsque les Skills sont listés dans l’invite, l’agent choisit-il le bon Skill (ou évite-t-il ceux qui ne sont pas pertinents) ? +- **Prise de décision :** lorsque des Skills sont listées dans le prompt, l’agent choisit-il la bonne Skill (ou évite-t-il celles qui ne sont pas pertinentes) ? - **Conformité :** l’agent lit-il `SKILL.md` avant utilisation et suit-il les étapes/arguments requis ? -- **Contrats de flux de travail :** scénarios multi-tours qui vérifient l’ordre des outils, la persistance de l’historique de session et les limites du bac à sable. +- **Contrats de workflow :** scénarios multi-tours qui vérifient l’ordre des outils, le report de l’historique de session et les limites du sandbox. Les futures évaluations doivent d’abord rester déterministes : -- Un exécuteur de scénarios utilisant des fournisseurs simulés pour vérifier les appels d’outils + leur ordre, les lectures de fichiers Skill et le câblage de session. -- Une petite suite de scénarios centrés sur les Skills (utiliser vs éviter, contrôle, injection d’invite). -- Des évaluations live facultatives (opt-in, contrôlées par env) uniquement après la mise en place de la suite compatible CI. +- Un exécuteur de scénarios utilisant des fournisseurs simulés pour vérifier les appels d’outils + leur ordre, les lectures de fichiers de Skill et le câblage des sessions. +- Une petite suite de scénarios centrés sur les Skills (utiliser vs éviter, garde-fous, injection de prompt). +- Des évaluations live facultatives (opt-in, contrôlées par l’environnement) seulement après la mise en place de la suite compatible CI. -## Tests de contrat (forme des Plugins et des canaux) +## Tests de contrat (forme des plugins et des canaux) -Les tests de contrat vérifient que chaque Plugin et canal enregistré respecte son -contrat d’interface. Ils parcourent tous les Plugins découverts et exécutent une suite d’assertions -sur la forme et le comportement. La voie unitaire par défaut `pnpm test` ignore volontairement -ces fichiers de seam partagé et de smoke ; exécutez explicitement les commandes de contrat -lorsque vous touchez aux surfaces partagées des canaux ou des fournisseurs. +Les tests de contrat vérifient que chaque plugin et canal enregistré respecte son +contrat d’interface. Ils itèrent sur tous les plugins découverts et exécutent une suite de +vérifications de forme et de comportement. La voie unitaire par défaut `pnpm test` +ignore intentionnellement ces fichiers partagés de raccord et de smoke ; exécutez explicitement +les commandes de contrat lorsque vous touchez des surfaces partagées de canal ou de fournisseur. ### Commandes - Tous les contrats : `pnpm test:contracts` -- Contrats de canaux uniquement : `pnpm test:contracts:channels` -- Contrats de fournisseurs uniquement : `pnpm test:contracts:plugins` +- Contrats de canal uniquement : `pnpm test:contracts:channels` +- Contrats de fournisseur uniquement : `pnpm test:contracts:plugins` -### Contrats de canaux +### Contrats de canal Situés dans `src/channels/plugins/contracts/*.contract.test.ts` : - **plugin** - Forme de base du Plugin (id, nom, capacités) - **setup** - Contrat de l’assistant de configuration -- **session-binding** - Comportement de liaison de session -- **outbound-payload** - Structure de la charge utile des messages +- **session-binding** - Comportement d’attachement de session +- **outbound-payload** - Structure de la charge des messages - **inbound** - Gestion des messages entrants -- **actions** - Gestionnaires d’actions de canal +- **actions** - Gestionnaires d’action du canal - **threading** - Gestion des identifiants de fil -- **directory** - API d’annuaire/liste +- **directory** - API d’annuaire/de liste - **group-policy** - Application de la politique de groupe -### Contrats d’état des fournisseurs +### Contrats de statut des fournisseurs Situés dans `src/plugins/contracts/*.contract.test.ts`. -- **status** - Sondes d’état des canaux -- **registry** - Forme du registre de Plugins +- **status** - Sondes de statut des canaux +- **registry** - Forme du registre de Plugin -### Contrats de fournisseurs +### Contrats des fournisseurs Situés dans `src/plugins/contracts/*.contract.test.ts` : - **auth** - Contrat de flux d’authentification - **auth-choice** - Choix/sélection d’authentification - **catalog** - API de catalogue de modèles -- **discovery** - Découverte de Plugins +- **discovery** - Découverte de Plugin - **loader** - Chargement de Plugin -- **runtime** - Exécution du fournisseur +- **runtime** - Runtime du fournisseur - **shape** - Forme/interface du Plugin - **wizard** - Assistant de configuration ### Quand les exécuter -- Après une modification des exports ou sous-chemins de plugin-sdk -- Après l’ajout ou la modification d’un Plugin de canal ou de fournisseur -- Après une refactorisation de l’enregistrement ou de la découverte des Plugins +- Après modification des exportations ou sous-chemins de plugin-sdk +- Après ajout ou modification d’un Plugin de canal ou de fournisseur +- Après refactorisation de l’enregistrement ou de la découverte des plugins -Les tests de contrat s’exécutent en CI et ne nécessitent pas de vraies clés API. +Les tests de contrat s’exécutent dans CI et ne nécessitent pas de vraies clés API. ## Ajouter des régressions (guide) Lorsque vous corrigez un problème de fournisseur/modèle découvert en live : -- Ajoutez si possible une régression compatible CI (fournisseur simulé/substitué, ou capture de la transformation exacte de la forme de requête) -- Si le problème est intrinsèquement live uniquement (limitations de débit, politiques d’authentification), gardez le test live restreint et opt-in via des variables d’environnement -- Préférez cibler la plus petite couche qui intercepte le bug : - - bug de conversion/rejeu de requête fournisseur → test direct de modèles - - bug du pipeline Gateway session/historique/outils → smoke live Gateway ou test Gateway simulé compatible CI +- Ajoutez si possible une régression compatible CI (fournisseur simulé/stub, ou capture de la transformation exacte de forme de requête) +- Si le problème est intrinsèquement limité au live (limites de débit, politiques d’authentification), gardez le test live étroit et opt-in via des variables d’environnement +- Préférez cibler la plus petite couche qui détecte le bogue : + - bogue de conversion/rejeu de requête fournisseur → test de modèles directs + - bogue de pipeline gateway session/historique/outils → smoke Gateway live ou test mock Gateway compatible CI - Garde-fou de traversée SecretRef : - - `src/secrets/exec-secret-ref-id-parity.test.ts` dérive une cible échantillon par classe SecretRef à partir des métadonnées du registre (`listSecretTargetRegistryEntries()`), puis vérifie que les identifiants exec de segment de traversée sont rejetés. - - Si vous ajoutez une nouvelle famille de cibles SecretRef `includeInPlan` dans `src/secrets/target-registry-data.ts`, mettez à jour `classifyTargetClass` dans ce test. Le test échoue volontairement sur les identifiants de cible non classifiés afin que de nouvelles classes ne puissent pas être ignorées silencieusement. + - `src/secrets/exec-secret-ref-id-parity.test.ts` dérive une cible échantillonnée par classe SecretRef à partir des métadonnées du registre (`listSecretTargetRegistryEntries()`), puis vérifie que les identifiants exec de segments de traversée sont rejetés. + - Si vous ajoutez une nouvelle famille de cibles SecretRef `includeInPlan` dans `src/secrets/target-registry-data.ts`, mettez à jour `classifyTargetClass` dans ce test. Le test échoue intentionnellement sur les identifiants de cible non classifiés afin qu’aucune nouvelle classe ne puisse être ignorée silencieusement. diff --git a/docs/fr/plugins/architecture.md b/docs/fr/plugins/architecture.md index 13fa8fc04..1dce2a8b4 100644 --- a/docs/fr/plugins/architecture.md +++ b/docs/fr/plugins/architecture.md @@ -1,17 +1,17 @@ --- read_when: - Créer ou déboguer des plugins OpenClaw natifs - - Comprendre le modèle de capacités des plugins ou les limites de responsabilité + - Comprendre le modèle de capacités des plugins ou les limites de propriété - Travailler sur le pipeline de chargement des plugins ou le registre - Implémenter des hooks d’exécution de fournisseur ou des plugins de canal sidebarTitle: Internals -summary: 'Internes du Plugin : modèle de capacités, propriété, contrats, pipeline de chargement et helpers d’exécution' +summary: 'Internes du Plugin : modèle de capacités, propriété, contrats, pipeline de chargement et assistants d’exécution' title: Internes du Plugin x-i18n: - generated_at: "2026-04-12T23:28:41Z" + generated_at: "2026-04-15T06:56:37Z" model: gpt-5.4 provider: openai - source_hash: 37361c1e9d2da57c77358396f19dfc7f749708b66ff68f1bf737d051b5d7675d + source_hash: f86798b5d2b0ad82d2397a52a6c21ed37fe6eee1dd3d124a9e4150c4f630b841 source_path: plugins/architecture.md workflow: 15 --- @@ -19,108 +19,108 @@ x-i18n: # Internes du Plugin - Il s’agit de la **référence d’architecture approfondie**. Pour des guides pratiques, voir : + Ceci est la **référence d’architecture approfondie**. Pour des guides pratiques, voir : - [Installer et utiliser des plugins](/fr/tools/plugin) — guide utilisateur - [Premiers pas](/fr/plugins/building-plugins) — premier tutoriel de plugin - [Plugins de canal](/fr/plugins/sdk-channel-plugins) — créer un canal de messagerie - [Plugins de fournisseur](/fr/plugins/sdk-provider-plugins) — créer un fournisseur de modèles - - [Vue d’ensemble du SDK](/fr/plugins/sdk-overview) — carte des imports et API d’enregistrement + - [Vue d’ensemble du SDK](/fr/plugins/sdk-overview) — table d’importation et API d’enregistrement -Cette page couvre l’architecture interne du système de plugins d’OpenClaw. +Cette page couvre l’architecture interne du système de plugins OpenClaw. -## Modèle public de capacités +## Modèle de capacités public -Les capacités constituent le modèle public de **plugin natif** dans OpenClaw. Chaque -plugin OpenClaw natif s’enregistre par rapport à un ou plusieurs types de capacités : +Les capacités constituent le modèle public des **plugins natifs** dans OpenClaw. Chaque +plugin OpenClaw natif s’enregistre auprès d’un ou plusieurs types de capacités : | Capability | Registration method | Example plugins | | ---------------------- | ------------------------------------------------ | ------------------------------------ | | Inférence de texte | `api.registerProvider(...)` | `openai`, `anthropic` | | Backend d’inférence CLI | `api.registerCliBackend(...)` | `openai`, `anthropic` | -| Voix | `api.registerSpeechProvider(...)` | `elevenlabs`, `microsoft` | +| Parole | `api.registerSpeechProvider(...)` | `elevenlabs`, `microsoft` | | Transcription en temps réel | `api.registerRealtimeTranscriptionProvider(...)` | `openai` | -| Voix en temps réel | `api.registerRealtimeVoiceProvider(...)` | `openai` | +| Voix en temps réel | `api.registerRealtimeVoiceProvider(...)` | `openai` | | Compréhension des médias | `api.registerMediaUnderstandingProvider(...)` | `openai`, `google` | | Génération d’images | `api.registerImageGenerationProvider(...)` | `openai`, `google`, `fal`, `minimax` | -| Génération musicale | `api.registerMusicGenerationProvider(...)` | `google`, `minimax` | -| Génération de vidéos | `api.registerVideoGenerationProvider(...)` | `qwen` | -| Récupération web | `api.registerWebFetchProvider(...)` | `firecrawl` | -| Recherche web | `api.registerWebSearchProvider(...)` | `google` | +| Génération de musique | `api.registerMusicGenerationProvider(...)` | `google`, `minimax` | +| Génération de vidéo | `api.registerVideoGenerationProvider(...)` | `qwen` | +| Récupération Web | `api.registerWebFetchProvider(...)` | `firecrawl` | +| Recherche Web | `api.registerWebSearchProvider(...)` | `google` | | Canal / messagerie | `api.registerChannel(...)` | `msteams`, `matrix` | Un plugin qui enregistre zéro capacité mais fournit des hooks, des outils ou -des services est un plugin **legacy hook-only**. Ce modèle reste entièrement pris en charge. +des services est un plugin **hérité uniquement basé sur des hooks**. Ce modèle reste entièrement pris en charge. ### Position de compatibilité externe -Le modèle de capacités est intégré au cœur et utilisé aujourd’hui par les plugins -bundled/natifs, mais la compatibilité des plugins externes exige toujours un critère +Le modèle de capacités est intégré au core et utilisé aujourd’hui par les plugins +bundlés/natifs, mais la compatibilité des plugins externes exige encore un critère plus strict que « c’est exporté, donc c’est figé ». -Consignes actuelles : +Recommandations actuelles : -- **plugins externes existants :** continuer à faire fonctionner les intégrations basées sur des hooks ; traiter - cela comme base de compatibilité -- **nouveaux plugins bundled/natifs :** préférer un enregistrement explicite des capacités plutôt que - des accès spécifiques à un fournisseur ou de nouvelles conceptions hook-only -- **plugins externes adoptant l’enregistrement de capacités :** autorisés, mais traiter les surfaces d’helpers - spécifiques aux capacités comme évolutives tant que la documentation ne marque pas explicitement +- **plugins externes existants :** garder les intégrations basées sur des hooks fonctionnelles ; considérer + cela comme la base de compatibilité +- **nouveaux plugins bundlés/natifs :** préférer l’enregistrement explicite de capacités aux + accès spécifiques à un fournisseur ou aux nouvelles conceptions uniquement basées sur des hooks +- **plugins externes adoptant l’enregistrement de capacités :** autorisé, mais considérer les + surfaces d’assistance spécifiques aux capacités comme évolutives, sauf si la documentation marque explicitement un contrat comme stable Règle pratique : -- les API d’enregistrement de capacités sont la direction visée -- les hooks legacy restent la voie la plus sûre pour éviter les ruptures pour les plugins externes pendant +- les API d’enregistrement de capacités sont la direction prévue +- les hooks hérités restent le chemin le plus sûr pour éviter les ruptures pour les plugins externes pendant la transition -- tous les sous-chemins d’helpers exportés ne se valent pas ; préférez le contrat documenté étroit, - pas des exports d’helpers incidentels +- les sous-chemins d’assistance exportés ne se valent pas tous ; préférer le contrat documenté et étroit, + pas des exportations d’assistance incidentes ### Formes de plugins -OpenClaw classe chaque plugin chargé dans une forme selon son comportement réel -d’enregistrement (et pas seulement selon des métadonnées statiques) : +OpenClaw classe chaque plugin chargé selon une forme basée sur son comportement +réel d’enregistrement (et pas seulement sur des métadonnées statiques) : - **plain-capability** -- enregistre exactement un type de capacité (par exemple un plugin uniquement fournisseur comme `mistral`) - **hybrid-capability** -- enregistre plusieurs types de capacités (par exemple - `openai` possède l’inférence de texte, la voix, la compréhension des médias et la génération - d’images) -- **hook-only** -- enregistre uniquement des hooks (typés ou personnalisés), sans - capacités, outils, commandes ou services -- **non-capability** -- enregistre des outils, commandes, services ou routes, mais aucune + `openai` possède l’inférence de texte, la parole, la compréhension des médias et la + génération d’images) +- **hook-only** -- enregistre uniquement des hooks (typés ou personnalisés), sans capacités, + outils, commandes ou services +- **non-capability** -- enregistre des outils, commandes, services ou routes mais aucune capacité -Utilisez `openclaw plugins inspect ` pour voir la forme d’un plugin et la -ventilation de ses capacités. Voir la [référence CLI](/cli/plugins#inspect) pour plus de détails. +Utilisez `openclaw plugins inspect ` pour voir la forme d’un plugin et la répartition +de ses capacités. Voir la [référence CLI](/cli/plugins#inspect) pour plus de détails. -### Hooks legacy +### Hooks hérités -Le hook `before_agent_start` reste pris en charge comme voie de compatibilité pour les -plugins hook-only. Des plugins legacy réels l’utilisent encore. +Le hook `before_agent_start` reste pris en charge comme voie de compatibilité pour +les plugins uniquement basés sur des hooks. Des plugins hérités réels en dépendent encore. Orientation : -- le laisser fonctionner -- le documenter comme legacy +- le conserver fonctionnel +- le documenter comme hérité - préférer `before_model_resolve` pour le travail de substitution de modèle/fournisseur -- préférer `before_prompt_build` pour le travail de mutation du prompt -- ne le retirer qu’une fois que l’usage réel aura diminué et que la couverture par fixtures prouvera la sûreté de la migration +- préférer `before_prompt_build` pour le travail de mutation des prompts +- ne le supprimer qu’une fois l’usage réel diminué et la couverture des fixtures prouvant la sécurité de la migration ### Signaux de compatibilité Lorsque vous exécutez `openclaw doctor` ou `openclaw plugins inspect `, vous pouvez voir -l’un de ces libellés : +l’une de ces étiquettes : | Signal | Signification | | -------------------------- | ------------------------------------------------------------ | -| **config valid** | La configuration est analysée correctement et les plugins se résolvent | +| **config valid** | La configuration est correctement analysée et les plugins sont résolus | | **compatibility advisory** | Le plugin utilise un modèle pris en charge mais plus ancien (par ex. `hook-only`) | | **legacy warning** | Le plugin utilise `before_agent_start`, qui est obsolète | | **hard error** | La configuration est invalide ou le plugin n’a pas pu être chargé | Ni `hook-only` ni `before_agent_start` ne casseront votre plugin aujourd’hui -- -`hook-only` est indicatif, et `before_agent_start` ne déclenche qu’un avertissement. Ces +`hook-only` est informatif, et `before_agent_start` ne déclenche qu’un avertissement. Ces signaux apparaissent aussi dans `openclaw status --all` et `openclaw plugins doctor`. ## Vue d’ensemble de l’architecture @@ -128,31 +128,30 @@ signaux apparaissent aussi dans `openclaw status --all` et `openclaw plugins doc Le système de plugins d’OpenClaw comporte quatre couches : 1. **Manifeste + découverte** - OpenClaw trouve les plugins candidats à partir des chemins configurés, des - racines d’espace de travail, des racines globales d’extensions et des extensions bundled. La découverte lit d’abord les - manifestes natifs `openclaw.plugin.json` ainsi que les manifestes de bundle pris en charge. + OpenClaw trouve les plugins candidats à partir des chemins configurés, des racines d’espace de travail, + des racines d’extensions globales et des extensions bundlées. La découverte lit d’abord les manifestes natifs + `openclaw.plugin.json` ainsi que les manifestes de bundles pris en charge. 2. **Activation + validation** - Le cœur décide si un plugin découvert est activé, désactivé, bloqué ou - sélectionné pour un slot exclusif tel que la mémoire. + Le core décide si un plugin découvert est activé, désactivé, bloqué ou + sélectionné pour un emplacement exclusif comme la mémoire. 3. **Chargement à l’exécution** - Les plugins OpenClaw natifs sont chargés dans le processus via jiti et enregistrent + Les plugins OpenClaw natifs sont chargés en processus via jiti et enregistrent des capacités dans un registre central. Les bundles compatibles sont normalisés en enregistrements de registre sans importer de code d’exécution. 4. **Consommation des surfaces** - Le reste d’OpenClaw lit le registre pour exposer les outils, canaux, configuration - des fournisseurs, hooks, routes HTTP, commandes CLI et services. + Le reste d’OpenClaw lit le registre pour exposer les outils, canaux, configuration des fournisseurs, hooks, routes HTTP, commandes CLI et services. -Pour la CLI des plugins en particulier, la découverte des commandes racines est scindée en deux phases : +Pour la CLI des plugins en particulier, la découverte des commandes racines est divisée en deux phases : -- les métadonnées d’analyse proviennent de `registerCli(..., { descriptors: [...] })` -- le véritable module CLI du plugin peut rester paresseux et s’enregistrer à la première invocation +- les métadonnées au moment de l’analyse proviennent de `registerCli(..., { descriptors: [...] })` +- le véritable module CLI du plugin peut rester paresseux et s’enregistrer lors de la première invocation -Cela permet de conserver le code CLI appartenant au plugin dans le plugin tout en laissant OpenClaw +Cela permet de conserver le code CLI appartenant au plugin à l’intérieur du plugin tout en laissant OpenClaw réserver les noms de commandes racines avant l’analyse. La limite de conception importante : -- la découverte + la validation de configuration doivent fonctionner à partir des **métadonnées de manifeste/schéma** +- la découverte + validation de configuration doivent fonctionner à partir des **métadonnées de manifeste/schéma** sans exécuter le code du plugin - le comportement d’exécution natif provient du chemin `register(api)` du module du plugin @@ -161,26 +160,34 @@ de construire des indications d’interface utilisateur/schéma avant que l’ex ### Plugins de canal et outil de message partagé -Les plugins de canal n’ont pas besoin d’enregistrer un outil distinct d’envoi/édition/réaction pour -les actions de chat normales. OpenClaw conserve un outil `message` partagé dans le cœur, et les -plugins de canal possèdent la découverte et l’exécution spécifiques au canal derrière celui-ci. +Les plugins de canal n’ont pas besoin d’enregistrer un outil séparé d’envoi/édition/réaction pour +les actions de chat normales. OpenClaw conserve un seul outil `message` partagé dans le core, et +les plugins de canal possèdent la découverte et l’exécution spécifiques au canal derrière celui-ci. La limite actuelle est la suivante : -- le cœur possède l’hôte de l’outil `message` partagé, le câblage du prompt, la tenue des - sessions/threads et la répartition de l’exécution -- les plugins de canal possèdent la découverte des actions à portée, la découverte des capacités et - tous les fragments de schéma spécifiques au canal -- les plugins de canal possèdent la grammaire de conversation de session spécifique au fournisseur, comme - la façon dont les identifiants de conversation encodent les identifiants de thread ou héritent des conversations parentes +- le core possède l’hôte de l’outil `message` partagé, le câblage des prompts, la + tenue de session/thread et la répartition de l’exécution +- les plugins de canal possèdent la découverte d’actions à portée limitée, la découverte de capacités et tous les fragments de schéma spécifiques au canal +- les plugins de canal possèdent la grammaire de conversation de session spécifique au fournisseur, par exemple + la manière dont les identifiants de conversation encodent les identifiants de thread ou héritent des conversations parentes - les plugins de canal exécutent l’action finale via leur adaptateur d’action Pour les plugins de canal, la surface SDK est `ChannelMessageActionAdapter.describeMessageTool(...)`. Cet appel de découverte unifié -permet à un plugin de retourner ensemble ses actions visibles, ses capacités et ses contributions de schéma afin -que ces éléments ne divergent pas. +permet à un plugin de renvoyer ensemble ses actions visibles, ses capacités et ses contributions au schéma +afin d’éviter toute dérive entre ces éléments. -Le cœur transmet la portée d’exécution à cette étape de découverte. Les champs importants incluent : +Lorsqu’un paramètre d’outil de message spécifique au canal transporte une source média telle qu’un +chemin local ou une URL de média distante, le plugin doit également renvoyer +`mediaSourceParams` depuis `describeMessageTool(...)`. Le core utilise cette liste explicite +pour appliquer la normalisation des chemins de sandbox et les indications d’accès média sortant +sans coder en dur les noms de paramètres appartenant au plugin. +Préférez ici des tables à portée d’action, et non une liste plate à l’échelle du canal, afin qu’un +paramètre média réservé au profil ne soit pas normalisé sur des actions sans rapport comme +`send`. + +Le core transmet la portée d’exécution dans cette étape de découverte. Les champs importants incluent : - `accountId` - `currentChannelId` @@ -191,123 +198,125 @@ Le cœur transmet la portée d’exécution à cette étape de découverte. Les - `agentId` - `requesterSenderId` entrant approuvé -Cela compte pour les plugins sensibles au contexte. Un canal peut masquer ou exposer -des actions de message en fonction du compte actif, de la room/du thread/du message courant, ou -de l’identité approuvée du demandeur sans coder en dur de branches spécifiques au canal dans l’outil -`message` du cœur. +Cela est important pour les plugins sensibles au contexte. Un canal peut masquer ou exposer +des actions de message en fonction du compte actif, de la salle/du thread/du message courant, ou +de l’identité de l’émetteur demandeur approuvée sans coder en dur des branches spécifiques au canal dans +l’outil `message` du core. -C’est pourquoi les changements de routage embedded-runner restent du travail de plugin : le runner est -responsable de transmettre l’identité actuelle de chat/session à la limite de découverte du plugin afin -que l’outil `message` partagé expose la bonne surface possédée par le canal pour le tour actuel. +C’est pourquoi les changements de routage de l’exécuteur embarqué restent du travail de plugin : l’exécuteur est +responsable de transmettre l’identité de chat/session courante dans la limite de découverte du plugin afin +que l’outil `message` partagé expose la bonne surface appartenant au canal pour le tour en cours. -Pour les helpers d’exécution appartenant au canal, les plugins bundled doivent conserver l’exécution -runtime dans leurs propres modules d’extension. Le cœur ne possède plus les runtimes d’action de message -Discord, Slack, Telegram ou WhatsApp sous `src/agents/tools`. -Nous ne publions pas de sous-chemins `plugin-sdk/*-action-runtime` séparés, et les plugins bundled -doivent importer directement leur propre code runtime local depuis leurs -modules possédés par l’extension. +Pour les assistants d’exécution appartenant au canal, les plugins bundlés doivent conserver l’exécution +dans leurs propres modules d’extension. Le core ne possède plus les +moteurs d’actions de message Discord, Slack, Telegram ou WhatsApp sous `src/agents/tools`. +Nous ne publions pas de sous-chemins séparés `plugin-sdk/*-action-runtime`, et les plugins bundlés +doivent importer directement leur propre code d’exécution local depuis leurs +modules appartenant à l’extension. -La même limite s’applique aux coutures SDK nommées par fournisseur en général : le cœur ne doit -pas importer de barrels de commodité spécifiques à un canal pour Slack, Discord, Signal, -WhatsApp ou des extensions similaires. Si le cœur a besoin d’un comportement, il doit soit -consommer le barrel `api.ts` / `runtime-api.ts` propre au plugin bundled, soit faire -remonter ce besoin en une capacité générique étroite dans le SDK partagé. +La même limite s’applique de manière générale aux jonctions SDK nommées d’après les fournisseurs : le core ne doit +pas importer de barrels de commodité spécifiques à un canal pour les extensions Slack, Discord, Signal, +WhatsApp ou similaires. Si le core a besoin d’un comportement, il doit soit consommer le +barrel `api.ts` / `runtime-api.ts` propre au plugin bundlé, soit promouvoir ce besoin +en une capacité générique étroite dans le SDK partagé. Pour les sondages en particulier, il existe deux chemins d’exécution : -- `outbound.sendPoll` est la base partagée pour les canaux qui correspondent au modèle commun +- `outbound.sendPoll` constitue la base partagée pour les canaux compatibles avec le modèle commun de sondage -- `actions.handleAction("poll")` est le chemin préféré pour une sémantique de sondage spécifique au canal ou des paramètres - de sondage supplémentaires +- `actions.handleAction("poll")` est le chemin préféré pour les sémantiques de sondage spécifiques au canal + ou pour des paramètres de sondage supplémentaires -Le cœur reporte désormais l’analyse partagée des sondages jusqu’à ce que la répartition du sondage du plugin refuse -l’action, afin que les gestionnaires de sondage appartenant au plugin puissent accepter des champs de sondage spécifiques au canal +Le core diffère désormais l’analyse partagée des sondages jusqu’à ce que la répartition du sondage du plugin refuse +l’action, afin que les gestionnaires de sondages appartenant au plugin puissent accepter des champs de sondage spécifiques au canal sans être bloqués d’abord par l’analyseur de sondage générique. Voir [Pipeline de chargement](#load-pipeline) pour la séquence complète de démarrage. ## Modèle de propriété des capacités -OpenClaw traite un plugin natif comme la limite de responsabilité pour une **entreprise** ou une -**fonctionnalité**, et non comme un fourre-tout d’intégrations sans lien. +OpenClaw traite un plugin natif comme la limite de propriété pour une **entreprise** ou une +**fonctionnalité**, et non comme un ensemble disparate d’intégrations sans lien. Cela signifie : -- un plugin d’entreprise doit généralement posséder toutes les surfaces OpenClaw de cette entreprise -- un plugin de fonctionnalité doit généralement posséder toute la surface de fonctionnalité qu’il introduit -- les canaux doivent consommer les capacités partagées du cœur au lieu de réimplémenter +- un plugin d’entreprise doit généralement posséder toutes les surfaces OpenClaw orientées + vers cette entreprise +- un plugin de fonctionnalité doit généralement posséder la surface complète de la fonctionnalité qu’il introduit +- les canaux doivent consommer les capacités partagées du core au lieu de réimplémenter de façon ad hoc le comportement des fournisseurs Exemples : -- le plugin bundled `openai` possède le comportement de fournisseur de modèles OpenAI ainsi que le comportement OpenAI - de voix + voix en temps réel + compréhension des médias + génération d’images -- le plugin bundled `elevenlabs` possède le comportement de voix ElevenLabs -- le plugin bundled `microsoft` possède le comportement de voix Microsoft -- le plugin bundled `google` possède le comportement de fournisseur de modèles Google ainsi que - le comportement Google de compréhension des médias + génération d’images + recherche web -- le plugin bundled `firecrawl` possède le comportement de récupération web Firecrawl -- les plugins bundled `minimax`, `mistral`, `moonshot` et `zai` possèdent leurs +- le plugin bundlé `openai` possède le comportement de fournisseur de modèles OpenAI ainsi que le + comportement OpenAI pour la parole + la voix en temps réel + la compréhension des médias + la génération d’images +- le plugin bundlé `elevenlabs` possède le comportement de parole ElevenLabs +- le plugin bundlé `microsoft` possède le comportement de parole Microsoft +- le plugin bundlé `google` possède le comportement de fournisseur de modèles Google ainsi que le + comportement Google pour la compréhension des médias + la génération d’images + la recherche Web +- le plugin bundlé `firecrawl` possède le comportement de récupération Web Firecrawl +- les plugins bundlés `minimax`, `mistral`, `moonshot` et `zai` possèdent leurs backends de compréhension des médias -- le plugin bundled `qwen` possède le comportement de fournisseur de texte Qwen ainsi que - la compréhension des médias et la génération de vidéos +- le plugin bundlé `qwen` possède le comportement de fournisseur de texte Qwen ainsi que le + comportement de compréhension des médias et de génération de vidéo - le plugin `voice-call` est un plugin de fonctionnalité : il possède le transport d’appel, les outils, - la CLI, les routes et le pontage de flux média Twilio, mais il consomme les capacités partagées - de voix + transcription en temps réel + voix en temps réel au lieu d’importer directement des plugins fournisseurs + la CLI, les routes et le pont de flux média Twilio, mais il consomme les capacités partagées de parole + ainsi que de transcription en temps réel et de voix en temps réel au lieu + d’importer directement des plugins de fournisseur L’état final visé est : -- OpenAI vit dans un seul plugin même si cela couvre les modèles de texte, la voix, les images et - de futures capacités vidéo -- un autre fournisseur peut faire de même pour sa propre surface fonctionnelle -- les canaux ne se soucient pas de savoir quel plugin fournisseur possède le provider ; ils consomment le - contrat de capacité partagée exposé par le cœur +- OpenAI vit dans un seul plugin même s’il couvre les modèles de texte, la parole, les images et + la vidéo à venir +- un autre fournisseur peut faire de même pour sa propre surface +- les canaux ne se préoccupent pas de savoir quel plugin fournisseur possède le fournisseur ; ils consomment le + contrat de capacité partagée exposé par le core C’est la distinction clé : -- **plugin** = limite de responsabilité -- **capability** = contrat du cœur que plusieurs plugins peuvent implémenter ou consommer +- **plugin** = limite de propriété +- **capability** = contrat du core que plusieurs plugins peuvent implémenter ou consommer Ainsi, si OpenClaw ajoute un nouveau domaine comme la vidéo, la première question n’est pas -« quel fournisseur devrait coder en dur la gestion de la vidéo ? » La première question est « quel est -le contrat de capacité vidéo du cœur ? » Une fois ce contrat en place, les plugins fournisseurs +« quel fournisseur doit coder en dur la gestion de la vidéo ? » La première question est « quel est +le contrat de capacité vidéo du core ? » Une fois ce contrat en place, les plugins fournisseurs peuvent s’y enregistrer et les plugins de canal/fonctionnalité peuvent le consommer. Si la capacité n’existe pas encore, la bonne démarche est généralement : -1. définir la capacité manquante dans le cœur -2. l’exposer via l’API/runtime du plugin de manière typée -3. raccorder les canaux/fonctionnalités à cette capacité -4. laisser les plugins fournisseurs enregistrer les implémentations +1. définir la capacité manquante dans le core +2. l’exposer via l’API/le runtime du plugin de manière typée +3. relier les canaux/fonctionnalités à cette capacité +4. laisser les plugins fournisseurs enregistrer des implémentations -Cela garde la responsabilité explicite tout en évitant un comportement du cœur dépendant d’un -seul fournisseur ou d’un chemin de code spécifique à un plugin unique. +Cela maintient une propriété explicite tout en évitant un comportement du core qui dépend +d’un seul fournisseur ou d’un chemin de code spécifique à un plugin ponctuel. ### Superposition des capacités Utilisez ce modèle mental pour décider où le code doit se trouver : -- **couche de capacité du cœur** : orchestration partagée, politique, repli, règles de fusion - de configuration, sémantique de livraison et contrats typés +- **couche de capacités du core** : orchestration partagée, politique, repli, règles de + fusion de configuration, sémantique de livraison et contrats typés - **couche de plugin fournisseur** : API spécifiques au fournisseur, authentification, catalogues de modèles, synthèse vocale, génération d’images, futurs backends vidéo, points de terminaison d’usage - **couche de plugin de canal/fonctionnalité** : intégration Slack/Discord/voice-call/etc. - qui consomme les capacités du cœur et les présente sur une surface + qui consomme les capacités du core et les présente sur une surface -Par exemple, le TTS suit cette forme : +Par exemple, TTS suit cette forme : -- le cœur possède la politique TTS au moment de la réponse, l’ordre de repli, les préférences et la livraison par canal +- le core possède la politique TTS au moment de la réponse, l’ordre de repli, les préférences et la livraison par canal - `openai`, `elevenlabs` et `microsoft` possèdent les implémentations de synthèse -- `voice-call` consomme le helper runtime TTS pour la téléphonie +- `voice-call` consomme l’assistant d’exécution TTS de téléphonie -Ce même modèle doit être préféré pour les capacités futures. +Ce même modèle doit être privilégié pour les capacités futures. -### Exemple de plugin d’entreprise multi-capacités +### Exemple de plugin d’entreprise à capacités multiples -Un plugin d’entreprise doit sembler cohérent vu de l’extérieur. Si OpenClaw dispose de -contrats partagés pour les modèles, la voix, la transcription en temps réel, la voix en temps réel, la -compréhension des médias, la génération d’images, la génération de vidéos, la récupération web et la recherche web, -un fournisseur peut posséder toutes ses surfaces en un seul endroit : +Un plugin d’entreprise doit sembler cohérent vu de l’extérieur. Si OpenClaw possède des +contrats partagés pour les modèles, la parole, la transcription en temps réel, la voix en temps +réel, la compréhension des médias, la génération d’images, la génération de vidéo, la récupération Web et la recherche Web, +un fournisseur peut posséder toutes ses surfaces au même endroit : ```ts import type { OpenClawPluginDefinition } from "openclaw/plugin-sdk/plugin-entry"; @@ -322,12 +331,12 @@ const plugin: OpenClawPluginDefinition = { register(api) { api.registerProvider({ id: "exampleai", - // auth/model catalog/runtime hooks + // hooks d’authentification/catalogue de modèles/d’exécution }); api.registerSpeechProvider({ id: "exampleai", - // vendor speech config — implement the SpeechProviderPlugin interface directly + // configuration de parole fournisseur — implémente directement l’interface SpeechProviderPlugin }); api.registerMediaUnderstandingProvider({ @@ -352,7 +361,7 @@ const plugin: OpenClawPluginDefinition = { api.registerWebSearchProvider( createPluginBackedWebSearchProvider({ id: "exampleai-search", - // credential + fetch logic + // logique d’identifiants + de récupération }), ); }, @@ -361,214 +370,216 @@ const plugin: OpenClawPluginDefinition = { export default plugin; ``` -Ce qui compte n’est pas le nom exact des helpers. C’est la forme qui compte : +Ce qui compte n’est pas le nom exact des assistants. C’est la forme qui compte : - un seul plugin possède la surface du fournisseur -- le cœur possède toujours les contrats de capacité -- les canaux et plugins de fonctionnalité consomment les helpers `api.runtime.*`, pas du code fournisseur +- le core possède toujours les contrats de capacité +- les plugins de canal et de fonctionnalité consomment des assistants `api.runtime.*`, pas du code fournisseur - les tests de contrat peuvent vérifier que le plugin a enregistré les capacités qu’il prétend posséder ### Exemple de capacité : compréhension vidéo OpenClaw traite déjà la compréhension d’image/audio/vidéo comme une seule -capacité partagée. Le même modèle de responsabilité s’y applique : +capacité partagée. Le même modèle de propriété s’y applique : -1. le cœur définit le contrat de compréhension des médias +1. le core définit le contrat de compréhension des médias 2. les plugins fournisseurs enregistrent `describeImage`, `transcribeAudio` et `describeVideo` selon le cas -3. les plugins de canal et de fonctionnalité consomment le comportement partagé du cœur au lieu de - se raccorder directement au code fournisseur +3. les plugins de canal et de fonctionnalité consomment le comportement partagé du core au lieu de + se connecter directement au code fournisseur -Cela évite d’intégrer dans le cœur les hypothèses vidéo d’un fournisseur donné. Le plugin possède -la surface fournisseur ; le cœur possède le contrat de capacité et le comportement de repli. +Cela évite d’intégrer dans le core les hypothèses vidéo d’un seul fournisseur. Le plugin possède +la surface du fournisseur ; le core possède le contrat de capacité et le comportement de repli. -La génération vidéo suit déjà cette même séquence : le cœur possède le contrat de -capacité typé et le helper runtime, et les plugins fournisseurs enregistrent des -implémentations `api.registerVideoGenerationProvider(...)` sur cette base. +La génération de vidéo utilise déjà cette même séquence : le core possède le contrat de +capacité typé et l’assistant d’exécution, et les plugins fournisseurs enregistrent +des implémentations `api.registerVideoGenerationProvider(...)` dessus. -Besoin d’une checklist concrète de déploiement ? Voir -[Capability Cookbook](/fr/plugins/architecture). +Besoin d’une checklist de déploiement concrète ? Voir +[Recueil de recettes des capacités](/fr/plugins/architecture). ## Contrats et application -La surface de l’API des plugins est volontairement typée et centralisée dans -`OpenClawPluginApi`. Ce contrat définit les points d’enregistrement pris en charge et -les helpers runtime sur lesquels un plugin peut s’appuyer. +La surface de l’API de plugin est intentionnellement typée et centralisée dans +`OpenClawPluginApi`. Ce contrat définit les points d’enregistrement pris en charge ainsi que +les assistants d’exécution sur lesquels un plugin peut s’appuyer. Pourquoi c’est important : -- les auteurs de plugins disposent d’une norme interne stable -- le cœur peut rejeter une propriété dupliquée, par exemple deux plugins enregistrant le même +- les auteurs de plugins disposent d’une norme interne stable et unique +- le core peut rejeter les propriétés en double, par exemple deux plugins enregistrant le même id de fournisseur -- le démarrage peut faire remonter des diagnostics exploitables pour des enregistrements mal formés -- les tests de contrat peuvent faire respecter la responsabilité des plugins bundled et empêcher une dérive silencieuse +- le démarrage peut faire remonter des diagnostics exploitables pour un enregistrement mal formé +- les tests de contrat peuvent faire respecter la propriété des plugins bundlés et empêcher les dérives silencieuses Il existe deux couches d’application : -1. **application à l’enregistrement runtime** +1. **application de l’enregistrement à l’exécution** Le registre des plugins valide les enregistrements au chargement des plugins. Exemples : - ids de fournisseur dupliqués, ids de fournisseur de voix dupliqués et enregistrements - mal formés produisent des diagnostics de plugin au lieu d’un comportement indéfini. + des ids de fournisseur dupliqués, des ids de fournisseur de parole dupliqués et des + enregistrements mal formés produisent des diagnostics de plugin au lieu d’un comportement indéfini. 2. **tests de contrat** - Les plugins bundled sont capturés dans des registres de contrat pendant les exécutions de test afin - qu’OpenClaw puisse vérifier explicitement la responsabilité. Aujourd’hui cela est utilisé pour les - fournisseurs de modèles, les fournisseurs de voix, les fournisseurs de recherche web et la responsabilité - d’enregistrement bundled. + Les plugins bundlés sont capturés dans des registres de contrat pendant les exécutions de test afin qu’OpenClaw + puisse affirmer explicitement la propriété. Aujourd’hui, cela est utilisé pour les + fournisseurs de modèles, les fournisseurs de parole, les fournisseurs de recherche Web et la propriété + des enregistrements bundlés. L’effet pratique est qu’OpenClaw sait, dès le départ, quel plugin possède quelle -surface. Cela permet au cœur et aux canaux de se composer sans friction, car la responsabilité est +surface. Cela permet au core et aux canaux de se composer de manière fluide, car la propriété est déclarée, typée et testable plutôt qu’implicite. -### Ce qui doit figurer dans un contrat +### Ce qui doit appartenir à un contrat Les bons contrats de plugin sont : - typés - petits - spécifiques à une capacité -- possédés par le cœur +- possédés par le core - réutilisables par plusieurs plugins -- consommables par des canaux/fonctionnalités sans connaissance du fournisseur +- consommables par les canaux/fonctionnalités sans connaissance du fournisseur Les mauvais contrats de plugin sont : -- une politique spécifique à un fournisseur cachée dans le cœur -- des échappatoires ponctuelles pour plugin qui contournent le registre +- une politique spécifique au fournisseur cachée dans le core +- des échappatoires ponctuelles de plugin qui contournent le registre - du code de canal accédant directement à une implémentation fournisseur -- des objets runtime ad hoc qui ne font pas partie de `OpenClawPluginApi` ou +- des objets d’exécution ad hoc qui ne font pas partie de `OpenClawPluginApi` ou de `api.runtime` -En cas de doute, montez le niveau d’abstraction : définissez d’abord la capacité, puis +En cas de doute, augmentez le niveau d’abstraction : définissez d’abord la capacité, puis laissez les plugins s’y brancher. ## Modèle d’exécution -Les plugins OpenClaw natifs s’exécutent **dans le processus** avec la Gateway. Ils ne sont -pas sandboxés. Un plugin natif chargé a la même limite de confiance au niveau du processus que le code du cœur. +Les plugins OpenClaw natifs s’exécutent **dans le même processus** que la Gateway. Ils ne sont pas +sandboxés. Un plugin natif chargé a la même limite de confiance au niveau du processus que +le code du core. Implications : -- un plugin natif peut enregistrer des outils, gestionnaires réseau, hooks et services -- un bogue de plugin natif peut faire planter ou déstabiliser la gateway +- un plugin natif peut enregistrer des outils, des gestionnaires réseau, des hooks et des services +- un bug dans un plugin natif peut faire planter ou déstabiliser la gateway - un plugin natif malveillant équivaut à une exécution de code arbitraire dans le processus OpenClaw -Les bundles compatibles sont plus sûrs par défaut, car OpenClaw les traite actuellement +Les bundles compatibles sont plus sûrs par défaut parce qu’OpenClaw les traite actuellement comme des packs de métadonnées/contenu. Dans les versions actuelles, cela signifie surtout des -Skills bundled. +Skills bundlées. -Utilisez des listes d’autorisation et des chemins explicites d’installation/chargement pour les plugins non bundled. Considérez +Utilisez des listes d’autorisation et des chemins d’installation/de chargement explicites pour les plugins non bundlés. Traitez les plugins d’espace de travail comme du code de développement, pas comme des valeurs par défaut de production. -Pour les noms de paquets bundled d’espace de travail, gardez l’id du plugin ancré dans le nom npm : -`@openclaw/` par défaut, ou un suffixe typé approuvé tel que +Pour les noms de packages d’espace de travail bundlés, gardez l’id du plugin ancré dans le +nom npm : `@openclaw/` par défaut, ou un suffixe typé approuvé tel que `-provider`, `-plugin`, `-speech`, `-sandbox` ou `-media-understanding` lorsque -le paquet expose intentionnellement un rôle de plugin plus étroit. +le package expose intentionnellement un rôle de plugin plus étroit. -Note de confiance importante : +Note importante sur la confiance : - `plugins.allow` fait confiance aux **ids de plugin**, pas à la provenance de la source. -- Un plugin d’espace de travail ayant le même id qu’un plugin bundled masque intentionnellement - la copie bundled lorsque ce plugin d’espace de travail est activé/sur liste d’autorisation. -- C’est normal et utile pour le développement local, les tests de correctifs et les hotfixes. +- Un plugin d’espace de travail avec le même id qu’un plugin bundlé masque intentionnellement + la copie bundlée lorsque ce plugin d’espace de travail est activé/autorisé. +- C’est normal et utile pour le développement local, les tests de correctifs et les correctifs urgents. -## Limite d’export +## Limite d’exportation -OpenClaw exporte des capacités, pas des commodités d’implémentation. +OpenClaw exporte des capacités, pas une commodité d’implémentation. -Gardez public l’enregistrement des capacités. Réduisez les exports d’helpers hors contrat : +Gardez l’enregistrement des capacités public. Réduisez les exportations d’assistance hors contrat : -- sous-chemins d’helpers spécifiques à un plugin bundled -- sous-chemins de plomberie runtime non destinés à être une API publique -- helpers de commodité spécifiques à un fournisseur -- helpers de configuration/intégration qui sont des détails d’implémentation +- sous-chemins d’assistance spécifiques à un plugin bundlé +- sous-chemins de plomberie d’exécution non destinés à être une API publique +- assistants de commodité spécifiques à un fournisseur +- assistants de configuration/d’onboarding qui sont des détails d’implémentation -Certains sous-chemins d’helpers de plugins bundled restent encore dans la carte d’exports SDK générée -pour la compatibilité et la maintenance des plugins bundled. Exemples actuels : +Certains sous-chemins d’assistance de plugins bundlés restent encore dans la table d’exportation générée du SDK pour la compatibilité et la maintenance des plugins bundlés. Exemples actuels : `plugin-sdk/feishu`, `plugin-sdk/feishu-setup`, `plugin-sdk/zalo`, -`plugin-sdk/zalo-setup` et plusieurs coutures `plugin-sdk/matrix*`. Traitez-les comme des -exports réservés de détail d’implémentation, et non comme le modèle SDK recommandé pour de nouveaux plugins tiers. +`plugin-sdk/zalo-setup` et plusieurs jonctions `plugin-sdk/matrix*`. Traitez-les comme des +exportations réservées aux détails d’implémentation, et non comme le modèle SDK recommandé pour +les nouveaux plugins tiers. ## Pipeline de chargement -Au démarrage, OpenClaw fait approximativement ceci : +Au démarrage, OpenClaw effectue approximativement ceci : -1. découvrir les racines de plugins candidates -2. lire les manifestes natifs ou de bundles compatibles et les métadonnées de paquet -3. rejeter les candidats non sûrs -4. normaliser la configuration des plugins (`plugins.enabled`, `allow`, `deny`, `entries`, +1. découvre les racines candidates de plugins +2. lit les manifestes natifs ou de bundle compatible ainsi que les métadonnées des packages +3. rejette les candidats non sûrs +4. normalise la configuration des plugins (`plugins.enabled`, `allow`, `deny`, `entries`, `slots`, `load.paths`) -5. décider de l’activation pour chaque candidat -6. charger les modules natifs activés via jiti -7. appeler les hooks natifs `register(api)` (ou `activate(api)` — un alias legacy) et collecter les enregistrements dans le registre des plugins -8. exposer le registre aux surfaces de commandes/runtime +5. décide de l’activation pour chaque candidat +6. charge les modules natifs activés via jiti +7. appelle les hooks natifs `register(api)` (ou `activate(api)` — un alias hérité) et collecte les enregistrements dans le registre des plugins +8. expose le registre aux surfaces des commandes/de l’exécution -`activate` est un alias legacy de `register` — le chargeur résout celui qui est présent (`def.register ?? def.activate`) et l’appelle au même moment. Tous les plugins bundled utilisent `register` ; préférez `register` pour les nouveaux plugins. +`activate` est un alias hérité de `register` — le chargeur résout celui qui est présent (`def.register ?? def.activate`) et l’appelle au même point. Tous les plugins bundlés utilisent `register` ; préférez `register` pour les nouveaux plugins. -Les garde-fous de sécurité s’appliquent **avant** l’exécution runtime. Les candidats sont bloqués -lorsque le point d’entrée sort de la racine du plugin, que le chemin est accessible en écriture à tous, ou que la propriété du chemin paraît suspecte pour des plugins non bundled. +Les contrôles de sécurité ont lieu **avant** l’exécution du runtime. Les candidats sont bloqués +lorsque l’entrée sort de la racine du plugin, que le chemin est accessible en écriture par tous, ou que la propriété du chemin semble suspecte pour les plugins non bundlés. ### Comportement manifest-first Le manifeste est la source de vérité du plan de contrôle. OpenClaw l’utilise pour : - identifier le plugin -- découvrir les canaux/Skills/schéma de configuration déclarés ou les capacités du bundle +- découvrir les canaux/Skills/schémas de configuration déclarés ou les capacités du bundle - valider `plugins.entries..config` -- enrichir les libellés/placeholders de la Control UI -- afficher les métadonnées d’installation/catalogue -- préserver des descripteurs bon marché d’activation et de configuration sans charger le runtime du plugin +- enrichir les étiquettes/placeholders de la Control UI +- afficher les métadonnées d’installation/de catalogue +- préserver des descripteurs d’activation et de configuration peu coûteux sans charger le runtime du plugin -Pour les plugins natifs, le module runtime est la partie plan de données. Il enregistre le -comportement réel tel que hooks, outils, commandes ou flux de fournisseur. +Pour les plugins natifs, le module d’exécution est la partie plan de données. Il enregistre le +comportement réel comme les hooks, outils, commandes ou flux de fournisseur. -Les blocs optionnels `activation` et `setup` du manifeste restent sur le plan de contrôle. -Ce sont des descripteurs de métadonnées uniquement pour la planification de l’activation et la découverte de configuration ; -ils ne remplacent pas l’enregistrement runtime, `register(...)` ni `setupEntry`. -Les premiers consommateurs d’activation réelle utilisent maintenant les indications de commande, de canal et de fournisseur du manifeste -pour restreindre le chargement des plugins avant une matérialisation plus large du registre : +Les blocs manifestes optionnels `activation` et `setup` restent sur le plan de contrôle. +Ce sont uniquement des descripteurs de métadonnées pour la planification de l’activation et la découverte de la configuration ; +ils ne remplacent pas l’enregistrement à l’exécution, `register(...)` ou `setupEntry`. +Les premiers consommateurs d’activation en direct utilisent désormais les indications de commandes, de canaux et de fournisseurs du manifeste +pour réduire le chargement des plugins avant une matérialisation plus large du registre : -- le chargement CLI se limite aux plugins qui possèdent la commande primaire demandée -- la résolution de configuration/plugin de canal se limite aux plugins qui possèdent l’id - de canal demandé -- la résolution explicite de configuration/runtime du fournisseur se limite aux plugins qui possèdent l’id - de fournisseur demandé +- le chargement CLI se réduit aux plugins qui possèdent la commande principale demandée +- la résolution de configuration/de plugin de canal se réduit aux plugins qui possèdent l’id de + canal demandé +- la résolution explicite de configuration/d’exécution de fournisseur se réduit aux plugins qui possèdent l’id de + fournisseur demandé -La découverte de configuration privilégie maintenant les ids possédés par des descripteurs tels que `setup.providers` et -`setup.cliBackends` pour restreindre les plugins candidats avant de retomber sur -`setup-api` pour les plugins qui ont encore besoin de hooks runtime au moment de la configuration. Si plusieurs -plugins découverts revendiquent le même id normalisé de fournisseur de configuration ou de backend CLI, la recherche de configuration refuse ce propriétaire ambigu au lieu de s’appuyer sur l’ordre de découverte. +La découverte de configuration préfère désormais les ids appartenant aux descripteurs, tels que `setup.providers` et +`setup.cliBackends`, pour réduire les plugins candidats avant de revenir à +`setup-api` pour les plugins qui ont encore besoin de hooks d’exécution au moment de la configuration. Si plus d’un +plugin découvert revendique le même id de fournisseur de configuration ou de backend CLI normalisé, +la recherche de configuration refuse le propriétaire ambigu au lieu de s’appuyer sur l’ordre de découverte. ### Ce que le chargeur met en cache -OpenClaw conserve de courts caches dans le processus pour : +OpenClaw conserve de courts caches en processus pour : - les résultats de découverte -- les données de registre de manifestes +- les données du registre des manifestes - les registres de plugins chargés -Ces caches réduisent les pointes de démarrage et la surcharge des commandes répétées. Il faut les considérer -comme des caches de performance à courte durée de vie, pas comme de la persistance. +Ces caches réduisent les démarrages en rafale et le coût des commandes répétées. Il est sûr +de les considérer comme des caches de performance de courte durée, et non comme de la persistance. -Remarque de performance : +Note de performance : - Définissez `OPENCLAW_DISABLE_PLUGIN_DISCOVERY_CACHE=1` ou `OPENCLAW_DISABLE_PLUGIN_MANIFEST_CACHE=1` pour désactiver ces caches. -- Réglez les fenêtres de cache avec `OPENCLAW_PLUGIN_DISCOVERY_CACHE_MS` et +- Ajustez les fenêtres de cache avec `OPENCLAW_PLUGIN_DISCOVERY_CACHE_MS` et `OPENCLAW_PLUGIN_MANIFEST_CACHE_MS`. ## Modèle de registre -Les plugins chargés ne modifient pas directement des globals arbitraires du cœur. Ils s’enregistrent dans un +Les plugins chargés ne modifient pas directement des globales arbitraires du core. Ils s’enregistrent dans un registre central de plugins. Le registre suit : -- les enregistrements de plugin (identité, source, origine, statut, diagnostics) +- les enregistrements de plugins (identité, source, origine, statut, diagnostics) - les outils -- les hooks legacy et hooks typés +- les hooks hérités et les hooks typés - les canaux - les fournisseurs - les gestionnaires RPC Gateway @@ -577,20 +588,22 @@ Le registre suit : - les services d’arrière-plan - les commandes appartenant au plugin -Les fonctionnalités du cœur lisent ensuite depuis ce registre au lieu de communiquer -directement avec les modules de plugin. Cela maintient un chargement à sens unique : +Les fonctionnalités du core lisent ensuite depuis ce registre au lieu de dialoguer directement avec les modules de plugin. +Cela maintient un chargement à sens unique : - module de plugin -> enregistrement dans le registre -- runtime du cœur -> consommation du registre +- runtime du core -> consommation du registre -Cette séparation est importante pour la maintenabilité. Elle signifie que la plupart des surfaces du cœur n’ont -besoin que d’un seul point d’intégration : « lire le registre », et non « gérer spécialement chaque module de plugin ». +Cette séparation est importante pour la maintenabilité. Elle signifie que la plupart des surfaces du core n’ont besoin +que d’un seul point d’intégration : « lire le registre », et non « gérer chaque module de plugin +comme un cas particulier ». ## Callbacks de liaison de conversation Les plugins qui lient une conversation peuvent réagir lorsqu’une approbation est résolue. -Utilisez `api.onConversationBindingResolved(...)` pour recevoir un callback après qu’une demande de liaison a été approuvée ou refusée : +Utilisez `api.onConversationBindingResolved(...)` pour recevoir un callback après qu’une demande de liaison +a été approuvée ou refusée : ```ts export default { @@ -598,12 +611,12 @@ export default { register(api) { api.onConversationBindingResolved(async (event) => { if (event.status === "approved") { - // A binding now exists for this plugin + conversation. + // Une liaison existe maintenant pour ce plugin + cette conversation. console.log(event.binding?.conversationId); return; } - // The request was denied; clear any local pending state. + // La demande a été refusée ; effacer tout état local en attente. console.log(event.request.conversation.conversationId); }); }, @@ -612,25 +625,25 @@ export default { Champs de la charge utile du callback : -- `status` : `"approved"` ou `"denied"` -- `decision` : `"allow-once"`, `"allow-always"` ou `"deny"` -- `binding` : la liaison résolue pour les demandes approuvées -- `request` : le résumé de la demande d’origine, l’indication de détachement, l’id de l’expéditeur et +- `status`: `"approved"` ou `"denied"` +- `decision`: `"allow-once"`, `"allow-always"` ou `"deny"` +- `binding`: la liaison résolue pour les demandes approuvées +- `request`: le résumé de la demande d’origine, l’indication de détachement, l’id d’expéditeur et les métadonnées de conversation -Ce callback est uniquement une notification. Il ne change pas qui est autorisé à lier une -conversation, et il s’exécute une fois que le traitement d’approbation du cœur est terminé. +Ce callback est uniquement une notification. Il ne modifie pas qui est autorisé à lier une +conversation, et il s’exécute une fois le traitement d’approbation du core terminé. -## Hooks d’exécution de fournisseur +## Hooks d’exécution des fournisseurs -Les plugins de fournisseur ont maintenant deux couches : +Les plugins de fournisseur ont désormais deux couches : -- métadonnées du manifeste : `providerAuthEnvVars` pour une recherche légère de l’authentification fournisseur par variable d’environnement +- métadonnées du manifeste : `providerAuthEnvVars` pour une recherche peu coûteuse de l’authentification fournisseur par variable d’environnement avant le chargement du runtime, `providerAuthAliases` pour les variantes de fournisseur qui partagent - l’authentification, `channelEnvVars` pour une recherche légère de la configuration/authentification de canal par variable d’environnement avant le chargement du runtime, - plus `providerAuthChoices` pour des libellés légers d’intégration/choix d’authentification et + l’authentification, `channelEnvVars` pour une recherche peu coûteuse de la configuration/authentification de canal via l’environnement avant le chargement du runtime, + ainsi que `providerAuthChoices` pour des étiquettes peu coûteuses d’onboarding/choix d’authentification et des métadonnées de drapeau CLI avant le chargement du runtime -- hooks au moment de la configuration : `catalog` / `discovery` legacy plus `applyConfigDefaults` +- hooks au moment de la configuration : `catalog` / `discovery` hérité ainsi que `applyConfigDefaults` - hooks d’exécution : `normalizeModelId`, `normalizeTransport`, `normalizeConfig`, `applyNativeStreamingUsageCompat`, `resolveConfigApiKey`, @@ -651,83 +664,87 @@ Les plugins de fournisseur ont maintenant deux couches : `buildReplayPolicy`, `sanitizeReplayHistory`, `validateReplayTurns`, `onModelSelected` -OpenClaw possède toujours la boucle d’agent générique, le failover, la gestion de transcription et -la politique d’outils. Ces hooks constituent la surface d’extension pour le comportement spécifique au fournisseur sans +OpenClaw possède toujours la boucle d’agent générique, le basculement, la gestion des transcriptions et la +politique des outils. Ces hooks sont la surface d’extension pour le comportement spécifique au fournisseur sans nécessiter tout un transport d’inférence personnalisé. -Utilisez le manifeste `providerAuthEnvVars` lorsque le fournisseur possède des identifiants basés sur l’environnement -que les chemins génériques d’authentification/statut/sélecteur de modèle doivent voir sans charger le runtime du plugin. Utilisez le manifeste `providerAuthAliases` lorsqu’un id de fournisseur doit réutiliser -les variables d’environnement, profils d’authentification, authentification basée sur la configuration et choix d’intégration de clé API d’un autre id de fournisseur. Utilisez le manifeste `providerAuthChoices` lorsque les surfaces CLI -d’intégration/choix d’authentification doivent connaître l’id de choix du fournisseur, les libellés de groupe et le câblage d’authentification simple à un seul drapeau sans charger le runtime du fournisseur. Conservez `envVars` dans le runtime du fournisseur pour des indications destinées à l’opérateur, comme les libellés d’intégration ou les -variables de configuration OAuth client-id/client-secret. +Utilisez le manifeste `providerAuthEnvVars` lorsque le fournisseur dispose d’identifiants basés sur l’environnement +que les chemins génériques d’authentification/statut/sélecteur de modèles doivent voir sans charger le runtime du plugin. Utilisez le manifeste `providerAuthAliases` lorsqu’un id de fournisseur doit réutiliser +les variables d’environnement, les profils d’authentification, l’authentification adossée à la configuration et le choix +d’onboarding de clé API d’un autre id de fournisseur. Utilisez le manifeste `providerAuthChoices` lorsque les +surfaces CLI d’onboarding/choix d’authentification doivent connaître l’id de choix du fournisseur, les libellés de groupe et un câblage +simple d’authentification à un seul drapeau sans charger le runtime du fournisseur. Conservez `envVars` dans le runtime du fournisseur pour +les indications orientées opérateur telles que les libellés d’onboarding ou les variables de configuration +client-id/client-secret OAuth. -Utilisez le manifeste `channelEnvVars` lorsqu’un canal possède une authentification ou une configuration pilotée par variables d’environnement que les retombées génériques d’environnement shell, les vérifications de configuration/statut ou les invites de configuration doivent voir +Utilisez le manifeste `channelEnvVars` lorsqu’un canal dispose d’une authentification ou d’une configuration pilotée par l’environnement que les +mécanismes génériques de repli sur l’environnement du shell, les vérifications de configuration/statut ou les invites de configuration doivent voir sans charger le runtime du canal. -### Ordre des hooks et utilisation +### Ordre et usage des hooks Pour les plugins de modèle/fournisseur, OpenClaw appelle les hooks dans cet ordre approximatif. -La colonne « Quand l’utiliser » est le guide rapide de décision. +La colonne « Quand l’utiliser » sert de guide de décision rapide. | # | Hook | Ce qu’il fait | Quand l’utiliser | | --- | --------------------------------- | -------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | -| 1 | `catalog` | Publie la configuration du fournisseur dans `models.providers` lors de la génération de `models.json` | Le fournisseur possède un catalogue ou des valeurs par défaut de base URL | +| 1 | `catalog` | Publie la configuration du fournisseur dans `models.providers` lors de la génération de `models.json` | Le fournisseur possède un catalogue ou des valeurs par défaut d’URL de base | | 2 | `applyConfigDefaults` | Applique les valeurs par défaut globales de configuration appartenant au fournisseur lors de la matérialisation de la configuration | Les valeurs par défaut dépendent du mode d’authentification, de l’environnement ou de la sémantique de famille de modèles du fournisseur | -| -- | _(built-in model lookup)_ | OpenClaw essaie d’abord le chemin normal de registre/catalogue | _(pas un hook de plugin)_ | -| 3 | `normalizeModelId` | Normalise les alias d’id de modèle legacy ou de préversion avant la recherche | Le fournisseur possède le nettoyage des alias avant la résolution canonique du modèle | +| -- | _(built-in model lookup)_ | OpenClaw essaie d’abord le chemin normal du registre/catalogue | _(pas un hook de plugin)_ | +| 3 | `normalizeModelId` | Normalise les alias d’id de modèle hérités ou de préversion avant la recherche | Le fournisseur possède le nettoyage des alias avant la résolution canonique du modèle | | 4 | `normalizeTransport` | Normalise `api` / `baseUrl` de la famille de fournisseurs avant l’assemblage générique du modèle | Le fournisseur possède le nettoyage du transport pour des ids de fournisseur personnalisés dans la même famille de transport | -| 5 | `normalizeConfig` | Normalise `models.providers.` avant la résolution runtime/fournisseur | Le fournisseur a besoin d’un nettoyage de configuration qui doit vivre avec le plugin ; les helpers bundled de la famille Google renforcent également les entrées de configuration Google prises en charge | -| 6 | `applyNativeStreamingUsageCompat` | Applique des réécritures de compatibilité d’usage de streaming natif aux fournisseurs de configuration | Le fournisseur a besoin de correctifs de métadonnées d’usage de streaming natif pilotés par le point de terminaison | -| 7 | `resolveConfigApiKey` | Résout l’authentification par marqueur d’environnement pour les fournisseurs de configuration avant le chargement de l’authentification runtime | Le fournisseur possède sa propre résolution de clé API par marqueur d’environnement ; `amazon-bedrock` a également ici un résolveur intégré de marqueur d’environnement AWS | -| 8 | `resolveSyntheticAuth` | Expose une authentification locale/autohébergée ou basée sur la configuration sans persister de texte brut | Le fournisseur peut fonctionner avec un marqueur d’identifiant synthétique/local | -| 9 | `resolveExternalAuthProfiles` | Superpose des profils d’authentification externes appartenant au fournisseur ; la `persistence` par défaut est `runtime-only` pour les identifiants détenus par CLI/app | Le fournisseur réutilise des identifiants d’authentification externes sans persister de jetons d’actualisation copiés | -| 10 | `shouldDeferSyntheticProfileAuth` | Abaisse la priorité des espaces réservés synthétiques stockés de profil derrière l’authentification basée sur l’environnement/la configuration | Le fournisseur stocke des profils espaces réservés synthétiques qui ne doivent pas avoir la priorité | -| 11 | `resolveDynamicModel` | Repli synchrone pour des ids de modèle appartenant au fournisseur mais pas encore présents dans le registre local | Le fournisseur accepte des ids de modèle amont arbitraires | -| 12 | `prepareDynamicModel` | Préchauffage asynchrone, puis `resolveDynamicModel` s’exécute à nouveau | Le fournisseur a besoin de métadonnées réseau avant de résoudre des ids inconnus | -| 13 | `normalizeResolvedModel` | Réécriture finale avant que l’embedded runner utilise le modèle résolu | Le fournisseur a besoin de réécritures de transport tout en utilisant un transport du cœur | -| 14 | `contributeResolvedModelCompat` | Ajoute des indicateurs de compatibilité pour les modèles fournisseur derrière un autre transport compatible | Le fournisseur reconnaît ses propres modèles sur des transports proxy sans prendre le contrôle du fournisseur | -| 15 | `capabilities` | Métadonnées de transcription/outillage appartenant au fournisseur utilisées par la logique partagée du cœur | Le fournisseur a besoin de particularités liées à la transcription/à la famille de fournisseurs | -| 16 | `normalizeToolSchemas` | Normalise les schémas d’outils avant que l’embedded runner ne les voie | Le fournisseur a besoin d’un nettoyage de schéma propre à la famille de transport | -| 17 | `inspectToolSchemas` | Expose des diagnostics de schéma appartenant au fournisseur après normalisation | Le fournisseur veut des avertissements sur les mots-clés sans enseigner au cœur des règles spécifiques au fournisseur | +| 5 | `normalizeConfig` | Normalise `models.providers.` avant la résolution du runtime/du fournisseur | Le fournisseur a besoin d’un nettoyage de configuration qui doit vivre avec le plugin ; les assistants bundlés de la famille Google servent aussi de filet de sécurité pour les entrées de configuration Google prises en charge | +| 6 | `applyNativeStreamingUsageCompat` | Applique aux fournisseurs de configuration des réécritures de compatibilité pour l’usage du streaming natif | Le fournisseur a besoin de corrections de métadonnées d’usage du streaming natif pilotées par point de terminaison | +| 7 | `resolveConfigApiKey` | Résout l’authentification par marqueur d’environnement pour les fournisseurs de configuration avant le chargement de l’authentification du runtime | Le fournisseur possède sa propre résolution de clé API par marqueur d’environnement ; `amazon-bedrock` dispose aussi ici d’un résolveur intégré de marqueur d’environnement AWS | +| 8 | `resolveSyntheticAuth` | Expose une authentification locale/autohébergée ou adossée à la configuration sans persister de texte brut | Le fournisseur peut fonctionner avec un marqueur d’identifiant synthétique/local | +| 9 | `resolveExternalAuthProfiles` | Superpose les profils d’authentification externe appartenant au fournisseur ; la `persistence` par défaut vaut `runtime-only` pour les identifiants possédés par la CLI/l’application | Le fournisseur réutilise des identifiants d’authentification externe sans persister de jetons de rafraîchissement copiés | +| 10 | `shouldDeferSyntheticProfileAuth` | Abaisse les espaces réservés de profils synthétiques stockés derrière l’authentification adossée à l’environnement/à la configuration | Le fournisseur stocke des profils d’espace réservé synthétiques qui ne doivent pas être prioritaires | +| 11 | `resolveDynamicModel` | Repli synchrone pour les ids de modèle appartenant au fournisseur qui ne sont pas encore dans le registre local | Le fournisseur accepte des ids de modèle amont arbitraires | +| 12 | `prepareDynamicModel` | Préparation asynchrone, puis `resolveDynamicModel` s’exécute à nouveau | Le fournisseur a besoin de métadonnées réseau avant de résoudre des ids inconnus | +| 13 | `normalizeResolvedModel` | Réécriture finale avant que l’exécuteur embarqué n’utilise le modèle résolu | Le fournisseur a besoin de réécritures de transport tout en utilisant un transport du core | +| 14 | `contributeResolvedModelCompat` | Contribue des indicateurs de compatibilité pour les modèles fournisseur derrière un autre transport compatible | Le fournisseur reconnaît ses propres modèles sur des transports proxy sans prendre le contrôle du fournisseur | +| 15 | `capabilities` | Métadonnées de transcription/d’outillage appartenant au fournisseur utilisées par la logique partagée du core | Le fournisseur a besoin de particularités liées aux transcriptions/à la famille de fournisseurs | +| 16 | `normalizeToolSchemas` | Normalise les schémas d’outils avant qu’ils ne soient vus par l’exécuteur embarqué | Le fournisseur a besoin d’un nettoyage de schéma lié à la famille de transport | +| 17 | `inspectToolSchemas` | Expose des diagnostics de schéma appartenant au fournisseur après normalisation | Le fournisseur veut des avertissements sur des mots-clés sans apprendre au core des règles spécifiques au fournisseur | | 18 | `resolveReasoningOutputMode` | Sélectionne le contrat de sortie de raisonnement natif ou balisé | Le fournisseur a besoin d’une sortie raisonnement/finale balisée au lieu de champs natifs | -| 19 | `prepareExtraParams` | Normalisation des paramètres de requête avant les wrappers génériques d’options de flux | Le fournisseur a besoin de paramètres de requête par défaut ou d’un nettoyage de paramètres par fournisseur | -| 20 | `createStreamFn` | Remplace entièrement le chemin de flux normal par un transport personnalisé | Le fournisseur a besoin d’un protocole filaire personnalisé, et pas seulement d’un wrapper | -| 21 | `wrapStreamFn` | Wrapper de flux après application des wrappers génériques | Le fournisseur a besoin de wrappers de compatibilité pour en-têtes/corps/modèle de requête sans transport personnalisé | -| 22 | `resolveTransportTurnState` | Attache des en-têtes ou métadonnées natives par tour de transport | Le fournisseur veut que les transports génériques envoient une identité de tour native au fournisseur | +| 19 | `prepareExtraParams` | Normalisation des paramètres de requête avant les wrappers génériques d’options de flux | Le fournisseur a besoin de paramètres de requête par défaut ou d’un nettoyage des paramètres par fournisseur | +| 20 | `createStreamFn` | Remplace entièrement le chemin de flux normal par un transport personnalisé | Le fournisseur a besoin d’un protocole réseau personnalisé, pas seulement d’un wrapper | +| 21 | `wrapStreamFn` | Wrapper de flux après application des wrappers génériques | Le fournisseur a besoin de wrappers de compatibilité pour les en-têtes/corps/modèles de requête sans transport personnalisé | +| 22 | `resolveTransportTurnState` | Attache des en-têtes ou métadonnées natives de transport par tour | Le fournisseur veut que les transports génériques envoient une identité de tour native au fournisseur | | 23 | `resolveWebSocketSessionPolicy` | Attache des en-têtes WebSocket natifs ou une politique de refroidissement de session | Le fournisseur veut que les transports WS génériques ajustent les en-têtes de session ou la politique de repli | -| 24 | `formatApiKey` | Formateur de profil d’authentification : le profil stocké devient la chaîne `apiKey` runtime | Le fournisseur stocke des métadonnées d’authentification supplémentaires et a besoin d’une forme de jeton runtime personnalisée | -| 25 | `refreshOAuth` | Surcharge d’actualisation OAuth pour des points de terminaison d’actualisation personnalisés ou une politique d’échec d’actualisation | Le fournisseur ne correspond pas aux actualisateurs partagés `pi-ai` | -| 26 | `buildAuthDoctorHint` | Indication de réparation ajoutée lorsque l’actualisation OAuth échoue | Le fournisseur a besoin d’une consigne de réparation d’authentification lui appartenant après un échec d’actualisation | -| 27 | `matchesContextOverflowError` | Correspondance d’erreur de dépassement de fenêtre de contexte appartenant au fournisseur | Le fournisseur a des erreurs brutes de dépassement que les heuristiques génériques manqueraient | -| 28 | `classifyFailoverReason` | Classification de motif de failover appartenant au fournisseur | Le fournisseur peut mapper des erreurs brutes d’API/transport en limite de débit/surcharge/etc. | -| 29 | `isCacheTtlEligible` | Politique de cache de prompt pour les fournisseurs proxy/backhaul | Le fournisseur a besoin d’un contrôle TTL de cache spécifique au proxy | -| 30 | `buildMissingAuthMessage` | Remplacement du message générique de récupération en cas d’authentification manquante | Le fournisseur a besoin d’une indication de récupération spécifique au fournisseur pour une authentification manquante | -| 31 | `suppressBuiltInModel` | Suppression de modèles amont obsolètes avec indication facultative d’erreur orientée utilisateur | Le fournisseur doit masquer des lignes amont obsolètes ou les remplacer par une indication fournisseur | -| 32 | `augmentModelCatalog` | Lignes de catalogue synthétiques/finales ajoutées après la découverte | Le fournisseur a besoin de lignes synthétiques de compatibilité ascendante dans `models list` et les sélecteurs | +| 24 | `formatApiKey` | Formateur de profil d’authentification : le profil stocké devient la chaîne `apiKey` du runtime | Le fournisseur stocke des métadonnées d’authentification supplémentaires et a besoin d’une forme de jeton d’exécution personnalisée | +| 25 | `refreshOAuth` | Surcharge du rafraîchissement OAuth pour des points de terminaison de rafraîchissement personnalisés ou une politique d’échec de rafraîchissement | Le fournisseur ne correspond pas aux mécanismes partagés de rafraîchissement `pi-ai` | +| 26 | `buildAuthDoctorHint` | Indication de réparation ajoutée lorsqu’un rafraîchissement OAuth échoue | Le fournisseur a besoin d’une indication de réparation d’authentification appartenant au fournisseur après un échec de rafraîchissement | +| 27 | `matchesContextOverflowError` | Détecteur de dépassement de fenêtre de contexte appartenant au fournisseur | Le fournisseur présente des erreurs brutes de dépassement que les heuristiques génériques ne détecteraient pas | +| 28 | `classifyFailoverReason` | Classification du motif de basculement appartenant au fournisseur | Le fournisseur peut mapper des erreurs brutes d’API/de transport vers limitation de débit/surcharge/etc. | +| 29 | `isCacheTtlEligible` | Politique de cache des prompts pour les fournisseurs proxy/backhaul | Le fournisseur a besoin d’un contrôle TTL de cache spécifique au proxy | +| 30 | `buildMissingAuthMessage` | Remplacement du message générique de récupération en cas d’authentification manquante | Le fournisseur a besoin d’une indication de récupération spécifique au fournisseur en cas d’authentification manquante | +| 31 | `suppressBuiltInModel` | Suppression des modèles amont obsolètes plus indication d’erreur optionnelle orientée utilisateur | Le fournisseur doit masquer des lignes amont obsolètes ou les remplacer par une indication fournisseur | +| 32 | `augmentModelCatalog` | Lignes de catalogue synthétiques/finales ajoutées après la découverte | Le fournisseur a besoin de lignes synthétiques de compatibilité future dans `models list` et les sélecteurs | | 33 | `isBinaryThinking` | Bascule de raisonnement activé/désactivé pour les fournisseurs à raisonnement binaire | Le fournisseur n’expose qu’un raisonnement binaire activé/désactivé | | 34 | `supportsXHighThinking` | Prise en charge du raisonnement `xhigh` pour certains modèles | Le fournisseur veut `xhigh` seulement sur un sous-ensemble de modèles | | 35 | `resolveDefaultThinkingLevel` | Niveau `/think` par défaut pour une famille de modèles spécifique | Le fournisseur possède la politique `/think` par défaut pour une famille de modèles | -| 36 | `isModernModelRef` | Correspondance de modèle moderne pour les filtres de profil en direct et la sélection smoke | Le fournisseur possède la correspondance de modèle préféré pour les profils en direct/smoke | -| 37 | `prepareRuntimeAuth` | Échange un identifiant configuré contre le jeton/la clé runtime réel juste avant l’inférence | Le fournisseur a besoin d’un échange de jeton ou d’un identifiant de requête à courte durée de vie | +| 36 | `isModernModelRef` | Détecteur de modèle moderne pour les filtres de profils en direct et la sélection smoke | Le fournisseur possède la correspondance des modèles préférés en direct/smoke | +| 37 | `prepareRuntimeAuth` | Échange un identifiant configuré contre le véritable jeton/clé du runtime juste avant l’inférence | Le fournisseur a besoin d’un échange de jeton ou d’un identifiant de requête de courte durée | | 38 | `resolveUsageAuth` | Résout les identifiants d’usage/facturation pour `/usage` et les surfaces d’état associées | Le fournisseur a besoin d’une analyse personnalisée des jetons d’usage/quota ou d’un identifiant d’usage différent | | 39 | `fetchUsageSnapshot` | Récupère et normalise des instantanés d’usage/quota spécifiques au fournisseur une fois l’authentification résolue | Le fournisseur a besoin d’un point de terminaison d’usage spécifique au fournisseur ou d’un analyseur de charge utile | -| 40 | `createEmbeddingProvider` | Construit un adaptateur d’embedding appartenant au fournisseur pour la mémoire/la recherche | Le comportement d’embedding de la mémoire appartient au plugin fournisseur | -| 41 | `buildReplayPolicy` | Retourne une politique de rejeu contrôlant la gestion de transcription pour le fournisseur | Le fournisseur a besoin d’une politique de transcription personnalisée (par exemple, suppression des blocs de réflexion) | -| 42 | `sanitizeReplayHistory` | Réécrit l’historique de rejeu après le nettoyage générique de transcription | Le fournisseur a besoin de réécritures de rejeu spécifiques au fournisseur au-delà des helpers partagés de Compaction | -| 43 | `validateReplayTurns` | Validation finale ou remise en forme des tours de rejeu avant l’embedded runner | Le transport fournisseur a besoin d’une validation plus stricte des tours après l’assainissement générique | -| 44 | `onModelSelected` | Exécute des effets de bord post-sélection appartenant au fournisseur | Le fournisseur a besoin de télémétrie ou d’un état appartenant au fournisseur lorsqu’un modèle devient actif | +| 40 | `createEmbeddingProvider` | Construit un adaptateur d’embedding appartenant au fournisseur pour la mémoire/la recherche | Le comportement d’embedding de la mémoire doit appartenir au plugin fournisseur | +| 41 | `buildReplayPolicy` | Renvoie une politique de rejeu contrôlant la gestion des transcriptions pour le fournisseur | Le fournisseur a besoin d’une politique de transcription personnalisée (par exemple, suppression des blocs de réflexion) | +| 42 | `sanitizeReplayHistory` | Réécrit l’historique de rejeu après le nettoyage générique des transcriptions | Le fournisseur a besoin de réécritures de rejeu spécifiques au fournisseur au-delà des assistants partagés de Compaction | +| 43 | `validateReplayTurns` | Validation finale ou restructuration des tours de rejeu avant l’exécuteur embarqué | Le transport du fournisseur a besoin d’une validation des tours plus stricte après l’assainissement générique | +| 44 | `onModelSelected` | Exécute des effets de bord post-sélection appartenant au fournisseur | Le fournisseur a besoin de télémétrie ou d’état appartenant au fournisseur lorsqu’un modèle devient actif | `normalizeModelId`, `normalizeTransport` et `normalizeConfig` vérifient d’abord le -plugin fournisseur correspondant, puis passent aux autres plugins fournisseurs capables de hooks -jusqu’à ce que l’un d’eux modifie effectivement l’id du modèle ou le transport/la configuration. Cela permet aux shims -d’alias/compatibilité de fournisseur de continuer à fonctionner sans obliger l’appelant à savoir quel -plugin bundled possède la réécriture. Si aucun hook fournisseur ne réécrit une entrée de configuration -prise en charge de la famille Google, le normaliseur de configuration Google bundled applique tout de même +plugin fournisseur correspondant, puis parcourent les autres plugins fournisseurs capables de hooks +jusqu’à ce que l’un d’eux modifie réellement l’id du modèle ou le transport/la configuration. Cela permet de conserver le bon fonctionnement +des shims d’alias/de compatibilité fournisseur sans obliger l’appelant à savoir quel +plugin bundlé possède la réécriture. Si aucun hook fournisseur ne réécrit une entrée de configuration +prise en charge de la famille Google, le normaliseur de configuration Google bundlé applique toujours ce nettoyage de compatibilité. -Si le fournisseur a besoin d’un protocole filaire entièrement personnalisé ou d’un exécuteur de requête -personnalisé, il s’agit d’une autre classe d’extension. Ces hooks sont destinés au comportement -fournisseur qui s’exécute encore sur la boucle d’inférence normale d’OpenClaw. +Si le fournisseur a besoin d’un protocole réseau entièrement personnalisé ou d’un exécuteur de requêtes personnalisé, +il s’agit d’une autre catégorie d’extension. Ces hooks sont destinés au comportement fournisseur +qui s’exécute toujours sur la boucle d’inférence normale d’OpenClaw. ### Exemple de fournisseur @@ -789,112 +806,111 @@ api.registerProvider({ `resolveUsageAuth`, `fetchUsageSnapshot`, `isCacheTtlEligible`, `resolveDefaultThinkingLevel`, `applyConfigDefaults`, `isModernModelRef`, et `wrapStreamFn` parce qu’il possède la compatibilité ascendante de Claude 4.6, - les indications de famille de fournisseur, les consignes de réparation d’authentification, l’intégration du point de terminaison d’usage, - l’éligibilité du cache de prompt, les valeurs par défaut de configuration sensibles à l’authentification, la politique - de réflexion par défaut/adaptative de Claude, et la mise en forme de flux spécifique à Anthropic pour les - en-têtes bêta, `/fast` / `serviceTier`, et `context1m`. -- Les helpers de flux spécifiques à Claude d’Anthropic restent pour l’instant dans la - couture publique propre au plugin bundled `api.ts` / `contract-api.ts`. Cette surface de paquet + les indications de famille de fournisseurs, les conseils de réparation d’authentification, l’intégration + du point de terminaison d’usage, l’éligibilité du cache de prompts, les valeurs par défaut de configuration tenant compte de l’authentification, la politique + de réflexion par défaut/adaptative de Claude, ainsi que la mise en forme de flux spécifique à Anthropic pour + les en-têtes bêta, `/fast` / `serviceTier` et `context1m`. +- Les assistants de flux spécifiques à Claude d’Anthropic restent pour l’instant dans la propre + jonction publique `api.ts` / `contract-api.ts` du plugin bundlé. Cette surface de package exporte `wrapAnthropicProviderStream`, `resolveAnthropicBetas`, - `resolveAnthropicFastMode`, `resolveAnthropicServiceTier`, et les builders de wrappers - Anthropic de plus bas niveau au lieu d’élargir le SDK générique autour des règles d’en-tête bêta d’un - seul fournisseur. + `resolveAnthropicFastMode`, `resolveAnthropicServiceTier` et les constructeurs de wrappers Anthropic + de plus bas niveau au lieu d’élargir le SDK générique autour des règles d’en-têtes bêta + d’un seul fournisseur. - OpenAI utilise `resolveDynamicModel`, `normalizeResolvedModel` et `capabilities` ainsi que `buildMissingAuthMessage`, `suppressBuiltInModel`, - `augmentModelCatalog`, `supportsXHighThinking`, et `isModernModelRef` + `augmentModelCatalog`, `supportsXHighThinking` et `isModernModelRef` parce qu’il possède la compatibilité ascendante de GPT-5.4, la normalisation directe OpenAI - `openai-completions` -> `openai-responses`, les - indications d’authentification conscientes de Codex, la suppression de Spark, les lignes de liste OpenAI synthétiques, et la politique - de réflexion / modèle en direct de GPT-5 ; la famille de flux `openai-responses-defaults` possède les - wrappers partagés natifs OpenAI Responses pour les en-têtes d’attribution, - `/fast`/`serviceTier`, la verbosité du texte, la recherche web native Codex, - la mise en forme de charge utile de compatibilité de raisonnement, et la gestion du contexte Responses. + `openai-completions` -> `openai-responses`, les indications d’authentification tenant compte de Codex, + la suppression de Spark, les lignes synthétiques de liste OpenAI et la politique de réflexion / + de modèle live de GPT-5 ; la famille de flux `openai-responses-defaults` possède les wrappers natifs partagés OpenAI Responses pour les en-têtes d’attribution, + `/fast`/`serviceTier`, la verbosité du texte, la recherche Web native Codex, + la mise en forme de charge utile de compatibilité du raisonnement et la gestion du contexte Responses. - OpenRouter utilise `catalog` ainsi que `resolveDynamicModel` et - `prepareDynamicModel` parce que le fournisseur est en transit et peut exposer de - nouveaux ids de modèle avant la mise à jour du catalogue statique d’OpenClaw ; il utilise aussi - `capabilities`, `wrapStreamFn` et `isCacheTtlEligible` pour garder hors du cœur - les en-têtes de requête spécifiques au fournisseur, les métadonnées de routage, les correctifs de raisonnement et - la politique de cache de prompt. Sa politique de rejeu provient de la + `prepareDynamicModel` parce que le fournisseur est en pass-through et peut exposer de nouveaux + ids de modèle avant la mise à jour du catalogue statique d’OpenClaw ; il utilise aussi + `capabilities`, `wrapStreamFn` et `isCacheTtlEligible` pour garder + hors du core les en-têtes de requête spécifiques au fournisseur, les métadonnées de routage, les correctifs de raisonnement et + la politique de cache de prompts. Sa politique de rejeu provient de la famille `passthrough-gemini`, tandis que la famille de flux `openrouter-thinking` - possède l’injection de raisonnement proxy et les sauts de modèle non pris en charge / `auto`. -- GitHub Copilot utilise `catalog`, `auth`, `resolveDynamicModel`, et + possède l’injection de raisonnement proxy et les contournements des modèles non pris en charge / `auto`. +- GitHub Copilot utilise `catalog`, `auth`, `resolveDynamicModel` et `capabilities` ainsi que `prepareRuntimeAuth` et `fetchUsageSnapshot` parce qu’il - a besoin d’une connexion par appareil appartenant au fournisseur, d’un comportement de repli de modèle, de - particularités de transcription Claude, d’un échange de jeton GitHub -> jeton Copilot, et d’un point de terminaison d’usage possédé par le fournisseur. + a besoin d’une connexion par appareil appartenant au fournisseur, d’un comportement de repli de modèle, de particularités de transcription Claude, + d’un échange de jeton GitHub -> jeton Copilot et d’un point de terminaison d’usage appartenant au fournisseur. - OpenAI Codex utilise `catalog`, `resolveDynamicModel`, - `normalizeResolvedModel`, `refreshOAuth`, et `augmentModelCatalog` ainsi que - `prepareExtraParams`, `resolveUsageAuth`, et `fetchUsageSnapshot` parce qu’il - fonctionne toujours sur les transports OpenAI du cœur mais possède sa propre normalisation du transport/de la base URL, - sa politique de repli d’actualisation OAuth, son choix de transport par défaut, - ses lignes de catalogue Codex synthétiques, et l’intégration du point de terminaison d’usage ChatGPT ; il - partage la même famille de flux `openai-responses-defaults` qu’OpenAI direct. + `normalizeResolvedModel`, `refreshOAuth` et `augmentModelCatalog` ainsi que + `prepareExtraParams`, `resolveUsageAuth` et `fetchUsageSnapshot` parce qu’il + s’exécute toujours sur les transports OpenAI du core, mais possède sa normalisation + de transport/d’URL de base, sa politique de repli de rafraîchissement OAuth, son choix de transport par défaut, + ses lignes synthétiques de catalogue Codex et son intégration du point de terminaison d’usage ChatGPT ; il + partage la même famille de flux `openai-responses-defaults` que l’OpenAI direct. - Google AI Studio et Gemini CLI OAuth utilisent `resolveDynamicModel`, `buildReplayPolicy`, `sanitizeReplayHistory`, - `resolveReasoningOutputMode`, `wrapStreamFn`, et `isModernModelRef` parce que la + `resolveReasoningOutputMode`, `wrapStreamFn` et `isModernModelRef` parce que la famille de rejeu `google-gemini` possède le repli de compatibilité ascendante de Gemini 3.1, - la validation native de rejeu Gemini, l’assainissement du rejeu bootstrap, le mode de - sortie de raisonnement balisé, et la correspondance de modèle moderne, tandis que la + la validation native du rejeu Gemini, l’assainissement du rejeu d’amorçage, le mode + de sortie de raisonnement balisé et la correspondance de modèles modernes, tandis que la famille de flux `google-thinking` possède la normalisation de charge utile de réflexion Gemini ; - Gemini CLI OAuth utilise aussi `formatApiKey`, `resolveUsageAuth`, et - `fetchUsageSnapshot` pour le formatage des jetons, l’analyse des jetons et le raccordement du point de terminaison de quota. + Gemini CLI OAuth utilise aussi `formatApiKey`, `resolveUsageAuth` et + `fetchUsageSnapshot` pour le formatage du jeton, l’analyse du jeton et le câblage du point de terminaison de quota. - Anthropic Vertex utilise `buildReplayPolicy` via la famille de rejeu `anthropic-by-model` afin que le nettoyage de rejeu spécifique à Claude reste - limité aux ids Claude au lieu de tous les transports `anthropic-messages`. + limité aux ids Claude au lieu de s’appliquer à tous les transports `anthropic-messages`. - Amazon Bedrock utilise `buildReplayPolicy`, `matchesContextOverflowError`, - `classifyFailoverReason`, et `resolveDefaultThinkingLevel` parce qu’il possède - la classification spécifique à Bedrock des erreurs de limitation/pas prêt/dépassement de contexte - pour le trafic Anthropic-sur-Bedrock ; sa politique de rejeu partage toujours la même - garde `anthropic-by-model` réservée à Claude. + `classifyFailoverReason` et `resolveDefaultThinkingLevel` parce qu’il possède + la classification spécifique à Bedrock des erreurs de limitation/non-prêt/dépassement de contexte + pour le trafic Anthropic-on-Bedrock ; sa politique de rejeu partage toujours la même + protection `anthropic-by-model` limitée à Claude. - OpenRouter, Kilocode, Opencode et Opencode Go utilisent `buildReplayPolicy` via la famille de rejeu `passthrough-gemini` parce qu’ils proxifient des modèles Gemini - via des transports compatibles OpenAI et ont besoin de - l’assainissement de signature de réflexion Gemini sans validation native du rejeu Gemini ni - réécritures bootstrap. + à travers des transports compatibles OpenAI et ont besoin de + l’assainissement de thought-signature Gemini sans validation native du rejeu Gemini ni + réécritures d’amorçage. - MiniMax utilise `buildReplayPolicy` via la - famille de rejeu `hybrid-anthropic-openai` parce qu’un seul fournisseur possède à la fois - la sémantique des messages Anthropic et la sémantique compatible OpenAI ; il conserve la suppression des - blocs de réflexion réservée à Claude du côté Anthropic tout en rétablissant le mode de sortie - de raisonnement en natif, et la famille de flux `minimax-fast-mode` possède les réécritures de modèle - fast-mode sur le chemin de flux partagé. + famille de rejeu `hybrid-anthropic-openai` parce qu’un même fournisseur possède à la fois des + sémantiques Anthropic-message et OpenAI-compatible ; il conserve l’abandon des + blocs de réflexion réservés à Claude côté Anthropic tout en rétablissant le mode de sortie + de raisonnement en mode natif, et la famille de flux `minimax-fast-mode` possède + les réécritures de modèles en mode rapide sur le chemin de flux partagé. - Moonshot utilise `catalog` ainsi que `wrapStreamFn` parce qu’il utilise toujours le transport OpenAI partagé mais a besoin d’une normalisation de charge utile de réflexion appartenant au fournisseur ; la famille de flux `moonshot-thinking` mappe la configuration ainsi que l’état `/think` sur sa charge utile native de réflexion binaire. -- Kilocode utilise `catalog`, `capabilities`, `wrapStreamFn`, et +- Kilocode utilise `catalog`, `capabilities`, `wrapStreamFn` et `isCacheTtlEligible` parce qu’il a besoin d’en-têtes de requête appartenant au fournisseur, - de normalisation de charge utile de raisonnement, d’indications de transcription Gemini, et d’un contrôle - Anthropic de TTL de cache ; la famille de flux `kilocode-thinking` conserve l’injection de réflexion Kilo - sur le chemin de flux proxy partagé tout en ignorant `kilo/auto` et les autres ids de modèle proxy - qui ne prennent pas en charge les charges utiles de raisonnement explicites. + d’une normalisation de charge utile de raisonnement, d’indications de transcription Gemini et d’un + contrôle TTL du cache Anthropic ; la famille de flux `kilocode-thinking` maintient l’injection + de réflexion Kilo sur le chemin de flux proxy partagé tout en ignorant `kilo/auto` et + d’autres ids de modèles proxy qui ne prennent pas en charge des charges utiles de raisonnement explicites. - Z.AI utilise `resolveDynamicModel`, `prepareExtraParams`, `wrapStreamFn`, `isCacheTtlEligible`, `isBinaryThinking`, `isModernModelRef`, - `resolveUsageAuth`, et `fetchUsageSnapshot` parce qu’il possède le repli GLM-5, - les valeurs par défaut `tool_stream`, l’UX de réflexion binaire, la correspondance de modèle moderne, et à la fois - l’authentification d’usage + la récupération de quota ; la famille de flux `tool-stream-default-on` - garde le wrapper `tool_stream` activé par défaut hors de la colle manuscrite par fournisseur. + `resolveUsageAuth` et `fetchUsageSnapshot` parce qu’il possède le repli GLM-5, + les valeurs par défaut de `tool_stream`, l’expérience utilisateur de réflexion binaire, la correspondance de modèles modernes et + à la fois l’authentification d’usage et la récupération de quota ; la famille de flux `tool-stream-default-on` maintient + hors du code de liaison manuscrit par fournisseur le wrapper `tool_stream` activé par défaut. - xAI utilise `normalizeResolvedModel`, `normalizeTransport`, `contributeResolvedModelCompat`, `prepareExtraParams`, `wrapStreamFn`, - `resolveSyntheticAuth`, `resolveDynamicModel`, et `isModernModelRef` - parce qu’il possède la normalisation native du transport xAI Responses, les réécritures d’alias - fast-mode Grok, `tool_stream` par défaut, le nettoyage strict-tool / charge utile de raisonnement, - la réutilisation d’authentification de repli pour les outils appartenant au plugin, la résolution ascendante - des modèles Grok, et les correctifs de compatibilité appartenant au fournisseur comme le profil - de schéma d’outil xAI, les mots-clés de schéma non pris en charge, `web_search` natif, et le décodage - des arguments d’appel d’outil avec entités HTML. -- Mistral, OpenCode Zen et OpenCode Go utilisent uniquement `capabilities` pour garder les - particularités de transcription/outillage hors du cœur. -- Les fournisseurs bundled uniquement catalogue tels que `byteplus`, `cloudflare-ai-gateway`, + `resolveSyntheticAuth`, `resolveDynamicModel` et `isModernModelRef` + parce qu’il possède la normalisation native du transport xAI Responses, les réécritures + d’alias Grok en mode rapide, la valeur par défaut `tool_stream`, le nettoyage strict-tool / charge utile de raisonnement, + la réutilisation d’authentification de repli pour les outils appartenant au plugin, la résolution de modèles Grok + à compatibilité ascendante et les correctifs de compatibilité appartenant au fournisseur, comme le profil de schéma d’outil xAI, + les mots-clés de schéma non pris en charge, `web_search` natif et le décodage des arguments d’appel d’outil + avec entités HTML. +- Mistral, OpenCode Zen et OpenCode Go utilisent uniquement `capabilities` afin de garder + hors du core les particularités de transcription/d’outillage. +- Les fournisseurs bundlés uniquement catalogue tels que `byteplus`, `cloudflare-ai-gateway`, `huggingface`, `kimi-coding`, `nvidia`, `qianfan`, - `synthetic`, `together`, `venice`, `vercel-ai-gateway`, et `volcengine` utilisent + `synthetic`, `together`, `venice`, `vercel-ai-gateway` et `volcengine` utilisent uniquement `catalog`. -- Qwen utilise `catalog` pour son fournisseur de texte ainsi que des enregistrements partagés de compréhension des médias et - de génération vidéo pour ses surfaces multimodales. -- MiniMax et Xiaomi utilisent `catalog` ainsi que les hooks d’usage parce que leur comportement `/usage` - appartient au plugin même si l’inférence s’exécute toujours via les transports partagés. +- Qwen utilise `catalog` pour son fournisseur de texte ainsi que les enregistrements partagés de compréhension des médias et + de génération de vidéo pour ses surfaces multimodales. +- MiniMax et Xiaomi utilisent `catalog` ainsi que des hooks d’usage, car leur comportement `/usage` + appartient au plugin même si l’inférence continue de s’exécuter via les transports partagés. -## Helpers runtime +## Assistants d’exécution -Les plugins peuvent accéder à certains helpers du cœur via `api.runtime`. Pour le TTS : +Les plugins peuvent accéder à certains assistants du core via `api.runtime`. Pour TTS : ```ts const clip = await api.runtime.tts.textToSpeech({ @@ -915,14 +931,14 @@ const voices = await api.runtime.tts.listVoices({ Remarques : -- `textToSpeech` renvoie la charge utile normale de sortie TTS du cœur pour les surfaces de fichier/note vocale. -- Utilise la configuration du cœur `messages.tts` et la sélection du fournisseur. -- Renvoie un buffer audio PCM + fréquence d’échantillonnage. Les plugins doivent rééchantillonner/encoder selon les fournisseurs. +- `textToSpeech` renvoie la charge utile de sortie TTS normale du core pour les surfaces fichier/note vocale. +- Utilise la configuration `messages.tts` du core et la sélection de fournisseur. +- Renvoie un tampon audio PCM + une fréquence d’échantillonnage. Les plugins doivent rééchantillonner/encoder pour les fournisseurs. - `listVoices` est facultatif selon le fournisseur. Utilisez-le pour les sélecteurs de voix appartenant au fournisseur ou les flux de configuration. -- Les listes de voix peuvent inclure des métadonnées plus riches comme la langue, le genre et des balises de personnalité pour des sélecteurs sensibles au fournisseur. -- OpenAI et ElevenLabs prennent aujourd’hui en charge la téléphonie. Microsoft non. +- Les listes de voix peuvent inclure des métadonnées plus riches telles que la locale, le genre et des tags de personnalité pour des sélecteurs tenant compte du fournisseur. +- OpenAI et ElevenLabs prennent aujourd’hui en charge la téléphonie. Microsoft ne la prend pas en charge. -Les plugins peuvent aussi enregistrer des fournisseurs de voix via `api.registerSpeechProvider(...)`. +Les plugins peuvent également enregistrer des fournisseurs de parole via `api.registerSpeechProvider(...)`. ```ts api.registerSpeechProvider({ @@ -942,15 +958,15 @@ api.registerSpeechProvider({ Remarques : -- Conservez dans le cœur la politique TTS, le repli et la livraison des réponses. -- Utilisez les fournisseurs de voix pour le comportement de synthèse appartenant au fournisseur. -- L’entrée legacy Microsoft `edge` est normalisée vers l’id de fournisseur `microsoft`. -- Le modèle de responsabilité préféré est orienté entreprise : un seul plugin fournisseur peut posséder - le texte, la voix, l’image et de futurs fournisseurs de médias à mesure qu’OpenClaw ajoute ces +- Conservez dans le core la politique TTS, le repli et la livraison des réponses. +- Utilisez des fournisseurs de parole pour le comportement de synthèse appartenant au fournisseur. +- L’entrée Microsoft héritée `edge` est normalisée vers l’id de fournisseur `microsoft`. +- Le modèle de propriété préféré est orienté entreprise : un plugin fournisseur peut posséder + les fournisseurs de texte, de parole, d’images et de futurs médias à mesure qu’OpenClaw ajoute ces contrats de capacité. -Pour la compréhension d’image/audio/vidéo, les plugins enregistrent un fournisseur typé unique -de compréhension des médias au lieu d’un sac clé/valeur générique : +Pour la compréhension d’image/audio/vidéo, les plugins enregistrent un fournisseur +typé unique de compréhension des médias au lieu d’un sac générique clé/valeur : ```ts api.registerMediaUnderstandingProvider({ @@ -964,16 +980,16 @@ api.registerMediaUnderstandingProvider({ Remarques : -- Conservez dans le cœur l’orchestration, le repli, la configuration et le câblage des canaux. -- Conservez le comportement fournisseur dans le plugin fournisseur. -- L’extension additive doit rester typée : nouvelles méthodes facultatives, nouveaux champs de résultat - facultatifs, nouvelles capacités facultatives. -- La génération vidéo suit déjà le même modèle : - - le cœur possède le contrat de capacité et le helper runtime +- Conservez dans le core l’orchestration, le repli, la configuration et le câblage des canaux. +- Conservez le comportement du fournisseur dans le plugin fournisseur. +- L’expansion additive doit rester typée : nouvelles méthodes facultatives, nouveaux champs de + résultat facultatifs, nouvelles capacités facultatives. +- La génération de vidéo suit déjà le même modèle : + - le core possède le contrat de capacité et l’assistant d’exécution - les plugins fournisseurs enregistrent `api.registerVideoGenerationProvider(...)` - les plugins de fonctionnalité/canal consomment `api.runtime.videoGeneration.*` -Pour les helpers runtime de compréhension des médias, les plugins peuvent appeler : +Pour les assistants d’exécution de compréhension des médias, les plugins peuvent appeler : ```ts const image = await api.runtime.mediaUnderstanding.describeImageFile({ @@ -995,7 +1011,7 @@ soit l’alias STT plus ancien : const { text } = await api.runtime.mediaUnderstanding.transcribeAudioFile({ filePath: "/tmp/inbound-audio.ogg", cfg: api.config, - // Optional when MIME cannot be inferred reliably: + // Facultatif lorsque le type MIME ne peut pas être déduit de façon fiable : mime: "audio/ogg", }); ``` @@ -1004,11 +1020,11 @@ Remarques : - `api.runtime.mediaUnderstanding.*` est la surface partagée privilégiée pour la compréhension d’image/audio/vidéo. -- Utilise la configuration audio de compréhension des médias du cœur (`tools.media.audio`) et l’ordre de repli du fournisseur. -- Renvoie `{ text: undefined }` lorsqu’aucune sortie de transcription n’est produite (par exemple en cas d’entrée ignorée/non prise en charge). +- Utilise la configuration audio de compréhension des médias du core (`tools.media.audio`) ainsi que l’ordre de repli des fournisseurs. +- Renvoie `{ text: undefined }` lorsqu’aucune sortie de transcription n’est produite (par exemple entrée ignorée/non prise en charge). - `api.runtime.stt.transcribeAudioFile(...)` reste disponible comme alias de compatibilité. -Les plugins peuvent aussi lancer des exécutions de sous-agent en arrière-plan via `api.runtime.subagent` : +Les plugins peuvent également lancer des exécutions de sous-agent en arrière-plan via `api.runtime.subagent` : ```ts const result = await api.runtime.subagent.run({ @@ -1022,14 +1038,14 @@ const result = await api.runtime.subagent.run({ Remarques : -- `provider` et `model` sont des surcharges facultatives par exécution, et non des changements persistants de session. -- OpenClaw ne respecte ces champs de surcharge que pour les appelants approuvés. -- Pour les exécutions de repli appartenant au plugin, les opérateurs doivent activer cela explicitement avec `plugins.entries..subagent.allowModelOverride: true`. -- Utilisez `plugins.entries..subagent.allowedModels` pour limiter les plugins approuvés à des cibles canoniques `provider/model` spécifiques, ou `"*"` pour autoriser explicitement toute cible. -- Les exécutions de sous-agent de plugins non approuvés fonctionnent toujours, mais les demandes de surcharge sont rejetées au lieu de retomber silencieusement sur autre chose. +- `provider` et `model` sont des surcharges facultatives par exécution, pas des changements persistants de session. +- OpenClaw n’honore ces champs de surcharge que pour les appelants de confiance. +- Pour les exécutions de repli appartenant au plugin, les opérateurs doivent explicitement activer `plugins.entries..subagent.allowModelOverride: true`. +- Utilisez `plugins.entries..subagent.allowedModels` pour restreindre les plugins de confiance à des cibles canoniques `provider/model` spécifiques, ou `"*"` pour autoriser explicitement n’importe quelle cible. +- Les exécutions de sous-agent de plugins non fiables continuent de fonctionner, mais les demandes de surcharge sont rejetées au lieu d’être silencieusement remplacées par un repli. -Pour la recherche web, les plugins peuvent consommer le helper runtime partagé au lieu -d’accéder au câblage de l’outil d’agent : +Pour la recherche Web, les plugins peuvent consommer l’assistant d’exécution partagé au lieu +d’accéder directement au câblage de l’outil agent : ```ts const providers = api.runtime.webSearch.listProviders({ @@ -1045,14 +1061,14 @@ const result = await api.runtime.webSearch.search({ }); ``` -Les plugins peuvent aussi enregistrer des fournisseurs de recherche web via +Les plugins peuvent également enregistrer des fournisseurs de recherche Web via `api.registerWebSearchProvider(...)`. Remarques : -- Conservez dans le cœur la sélection du fournisseur, la résolution des identifiants et la sémantique de requête partagée. -- Utilisez des fournisseurs de recherche web pour les transports de recherche spécifiques au fournisseur. -- `api.runtime.webSearch.*` est la surface partagée privilégiée pour les plugins de fonctionnalité/canal qui ont besoin d’un comportement de recherche sans dépendre du wrapper de l’outil d’agent. +- Conservez dans le core la sélection du fournisseur, la résolution des identifiants et la sémantique partagée des requêtes. +- Utilisez des fournisseurs de recherche Web pour les transports de recherche spécifiques au fournisseur. +- `api.runtime.webSearch.*` est la surface partagée privilégiée pour les plugins de fonctionnalité/canal qui ont besoin d’un comportement de recherche sans dépendre du wrapper de l’outil agent. ### `api.runtime.imageGeneration` @@ -1067,7 +1083,7 @@ const providers = api.runtime.imageGeneration.listProviders({ }); ``` -- `generate(...)` : génère une image à l’aide de la chaîne configurée de fournisseurs de génération d’images. +- `generate(...)` : génère une image en utilisant la chaîne configurée de fournisseurs de génération d’images. - `listProviders(...)` : liste les fournisseurs de génération d’images disponibles et leurs capacités. ## Routes HTTP Gateway @@ -1089,35 +1105,35 @@ api.registerHttpRoute({ Champs de route : -- `path` : chemin de route sous le serveur HTTP de la gateway. -- `auth` : requis. Utilisez `"gateway"` pour exiger l’authentification normale de la gateway, ou `"plugin"` pour une authentification/validation de Webhook gérée par le plugin. +- `path` : chemin de route sous le serveur HTTP de la Gateway. +- `auth` : obligatoire. Utilisez `"gateway"` pour exiger l’authentification normale de la Gateway, ou `"plugin"` pour une authentification/validation de Webhook gérée par le plugin. - `match` : facultatif. `"exact"` (par défaut) ou `"prefix"`. -- `replaceExisting` : facultatif. Permet au même plugin de remplacer son propre enregistrement de route existant. +- `replaceExisting` : facultatif. Permet au même plugin de remplacer sa propre inscription de route existante. - `handler` : renvoie `true` lorsque la route a traité la requête. Remarques : - `api.registerHttpHandler(...)` a été supprimé et provoquera une erreur de chargement du plugin. Utilisez `api.registerHttpRoute(...)` à la place. -- Les routes de plugin doivent déclarer explicitement `auth`. +- Les routes de plugin doivent déclarer `auth` explicitement. - Les conflits exacts `path + match` sont rejetés sauf si `replaceExisting: true`, et un plugin ne peut pas remplacer la route d’un autre plugin. -- Les routes qui se chevauchent avec des niveaux `auth` différents sont rejetées. Gardez les chaînes de retombée `exact`/`prefix` au même niveau d’authentification uniquement. -- Les routes `auth: "plugin"` ne reçoivent **pas** automatiquement de portées runtime d’opérateur. Elles servent aux webhooks gérés par le plugin / à la vérification de signature, et non à des appels helper Gateway privilégiés. -- Les routes `auth: "gateway"` s’exécutent dans une portée runtime de requête Gateway, mais cette portée est volontairement prudente : - - l’authentification bearer par secret partagé (`gateway.auth.mode = "token"` / `"password"`) maintient les portées runtime des routes de plugin épinglées à `operator.write`, même si l’appelant envoie `x-openclaw-scopes` - - les modes HTTP approuvés portant une identité (par exemple `trusted-proxy` ou `gateway.auth.mode = "none"` sur une ingress privée) ne respectent `x-openclaw-scopes` que lorsque l’en-tête est explicitement présent - - si `x-openclaw-scopes` est absent sur ces requêtes de route de plugin portant une identité, la portée runtime retombe sur `operator.write` -- Règle pratique : ne supposez pas qu’une route de plugin authentifiée par gateway est implicitement une surface d’administration. Si votre route a besoin d’un comportement réservé à l’administration, exigez un mode d’authentification portant une identité et documentez le contrat explicite de l’en-tête `x-openclaw-scopes`. +- Les routes qui se chevauchent avec différents niveaux `auth` sont rejetées. Conservez les chaînes de retombée `exact`/`prefix` au même niveau d’authentification uniquement. +- Les routes `auth: "plugin"` ne reçoivent **pas** automatiquement les portées d’exécution opérateur. Elles sont destinées aux Webhooks/à la vérification de signature gérés par le plugin, et non aux appels privilégiés des assistants Gateway. +- Les routes `auth: "gateway"` s’exécutent dans une portée d’exécution de requête Gateway, mais cette portée est volontairement conservatrice : + - l’authentification bearer à secret partagé (`gateway.auth.mode = "token"` / `"password"`) maintient les portées d’exécution des routes de plugin fixées à `operator.write`, même si l’appelant envoie `x-openclaw-scopes` + - les modes HTTP fiables avec identité (par exemple `trusted-proxy` ou `gateway.auth.mode = "none"` sur une entrée privée) n’honorent `x-openclaw-scopes` que lorsque l’en-tête est explicitement présent + - si `x-openclaw-scopes` est absent sur ces requêtes de route de plugin avec identité, la portée d’exécution revient à `operator.write` +- Règle pratique : ne supposez pas qu’une route de plugin authentifiée par gateway constitue implicitement une surface d’administration. Si votre route a besoin d’un comportement réservé à l’administration, exigez un mode d’authentification avec identité et documentez le contrat explicite de l’en-tête `x-openclaw-scopes`. -## Chemins d’import du Plugin SDK +## Chemins d’importation du Plugin SDK -Utilisez les sous-chemins du SDK au lieu de l’import monolithique `openclaw/plugin-sdk` lorsque +Utilisez les sous-chemins du SDK au lieu de l’importation monolithique `openclaw/plugin-sdk` lorsque vous créez des plugins : - `openclaw/plugin-sdk/plugin-entry` pour les primitives d’enregistrement de plugin. - `openclaw/plugin-sdk/core` pour le contrat générique partagé orienté plugin. -- `openclaw/plugin-sdk/config-schema` pour l’export du schéma Zod racine `openclaw.json` +- `openclaw/plugin-sdk/config-schema` pour l’exportation du schéma Zod racine `openclaw.json` (`OpenClawSchema`). -- Primitives de canal stables telles que `openclaw/plugin-sdk/channel-setup`, +- Les primitives de canal stables telles que `openclaw/plugin-sdk/channel-setup`, `openclaw/plugin-sdk/setup-runtime`, `openclaw/plugin-sdk/setup-adapter-runtime`, `openclaw/plugin-sdk/setup-tools`, @@ -1128,19 +1144,19 @@ vous créez des plugins : `openclaw/plugin-sdk/channel-lifecycle`, `openclaw/plugin-sdk/channel-reply-pipeline`, `openclaw/plugin-sdk/command-auth`, - `openclaw/plugin-sdk/secret-input`, et - `openclaw/plugin-sdk/webhook-ingress` pour le câblage partagé - de configuration/authentification/réponse/Webhook. `channel-inbound` est l’emplacement partagé pour l’anti-rebond, la correspondance des mentions, - les helpers de politique de mention entrante, le formatage des enveloppes et les - helpers de contexte d’enveloppe entrante. - `channel-setup` est la couture étroite de configuration avec installation facultative. + `openclaw/plugin-sdk/secret-input` et + `openclaw/plugin-sdk/webhook-ingress` pour le câblage partagé de la configuration/de l’authentification/des réponses/des Webhooks. + `channel-inbound` est le foyer partagé pour l’anti-rebond, la correspondance de mentions, + les assistants de politique de mention entrante, le formatage d’enveloppe et les assistants de contexte + d’enveloppe entrante. + `channel-setup` est la jonction étroite de configuration d’installation facultative. `setup-runtime` est la surface de configuration sûre à l’exécution utilisée par `setupEntry` / - le démarrage différé, y compris les adaptateurs de patch de configuration sûrs à importer. - `setup-adapter-runtime` est la couture d’adaptateur de configuration de compte sensible à l’environnement. - `setup-tools` est la petite couture d’helpers CLI/archive/docs (`formatCliCommand`, + le démarrage différé, y compris les adaptateurs de patch de configuration sûrs à l’importation. + `setup-adapter-runtime` est la jonction d’adaptateur de configuration de compte tenant compte de l’environnement. + `setup-tools` est la petite jonction d’assistants CLI/archive/docs (`formatCliCommand`, `detectBinary`, `extractArchive`, `resolveBrewExecutable`, `formatDocsLink`, `CONFIG_DIR`). -- Sous-chemins de domaine tels que `openclaw/plugin-sdk/channel-config-helpers`, +- Les sous-chemins de domaine tels que `openclaw/plugin-sdk/channel-config-helpers`, `openclaw/plugin-sdk/allow-from`, `openclaw/plugin-sdk/channel-config-schema`, `openclaw/plugin-sdk/telegram-command-config`, @@ -1157,130 +1173,132 @@ vous créez des plugins : `openclaw/plugin-sdk/routing`, `openclaw/plugin-sdk/status-helpers`, `openclaw/plugin-sdk/text-runtime`, - `openclaw/plugin-sdk/runtime-store`, et - `openclaw/plugin-sdk/directory-runtime` pour les helpers partagés d’exécution/configuration. - `telegram-command-config` est la couture publique étroite pour la normalisation/validation des commandes personnalisées Telegram et reste disponible même si la surface de contrat Telegram bundled est temporairement indisponible. - `text-runtime` est la couture partagée de texte/Markdown/journalisation, y compris - la suppression de texte visible par l’assistant, les helpers de rendu/segmentation Markdown, les helpers de - rédaction, les helpers de balises de directive et les utilitaires de texte sûr. -- Les coutures de canal spécifiques à l’approbation doivent préférer un seul contrat - `approvalCapability` sur le plugin. Le cœur lit alors l’authentification d’approbation, la livraison, le rendu, - le routage natif et le comportement paresseux du gestionnaire natif via cette seule capacité - au lieu de mélanger le comportement d’approbation dans des champs de plugin non liés. -- `openclaw/plugin-sdk/channel-runtime` est obsolète et ne reste présent que comme - shim de compatibilité pour les anciens plugins. Le nouveau code doit importer les primitives - génériques plus étroites à la place, et le code du dépôt ne doit pas ajouter de nouveaux imports du + `openclaw/plugin-sdk/runtime-store` et + `openclaw/plugin-sdk/directory-runtime` pour les assistants partagés d’exécution/de configuration. + `telegram-command-config` est la jonction publique étroite pour la normalisation/validation des + commandes personnalisées Telegram et reste disponible même si la + surface de contrat Telegram bundlée est temporairement indisponible. + `text-runtime` est la jonction partagée texte/markdown/journalisation, incluant + la suppression du texte visible par l’assistant, les assistants de rendu/segmentation markdown, les assistants de masquage, + les assistants de balises de directive et les utilitaires de texte sûr. +- Les jonctions de canal spécifiques à l’approbation doivent préférer un seul contrat + `approvalCapability` sur le plugin. Le core lit ensuite l’authentification d’approbation, la livraison, le rendu, + le routage natif et le comportement différé du gestionnaire natif via cette unique capacité + au lieu de mélanger le comportement d’approbation dans des champs de plugin sans rapport. +- `openclaw/plugin-sdk/channel-runtime` est obsolète et ne reste que comme + shim de compatibilité pour les anciens plugins. Le nouveau code doit importer à la place les primitives génériques plus étroites, et le code du dépôt ne doit pas ajouter de nouveaux imports du shim. -- Les internes d’extensions bundled restent privés. Les plugins externes ne doivent utiliser que - les sous-chemins `openclaw/plugin-sdk/*`. Le code cœur/test d’OpenClaw peut utiliser les - points d’entrée publics du dépôt sous une racine de paquet de plugin tels que `index.js`, `api.js`, - `runtime-api.js`, `setup-entry.js`, et des fichiers à portée étroite tels que - `login-qr-api.js`. N’importez jamais le `src/*` d’un paquet de plugin depuis le cœur ou depuis +- Les éléments internes des extensions bundlées restent privés. Les plugins externes ne doivent utiliser que + les sous-chemins `openclaw/plugin-sdk/*`. Le code core/de test OpenClaw peut utiliser les + points d’entrée publics du dépôt sous une racine de package de plugin telle que `index.js`, `api.js`, + `runtime-api.js`, `setup-entry.js` et des fichiers à portée étroite comme + `login-qr-api.js`. N’importez jamais `src/*` d’un package de plugin depuis le core ou depuis une autre extension. -- Découpage des points d’entrée du dépôt : - `/api.js` est le barrel de helpers/types, - `/runtime-api.js` est le barrel runtime uniquement, - `/index.js` est le point d’entrée du plugin bundled, - et `/setup-entry.js` est le point d’entrée du plugin de configuration. -- Exemples actuels de fournisseurs bundled : - - Anthropic utilise `api.js` / `contract-api.js` pour les helpers de flux Claude tels - que `wrapAnthropicProviderStream`, les helpers d’en-tête bêta, et l’analyse de `service_tier`. - - OpenAI utilise `api.js` pour les builders de fournisseur, les helpers de modèle par défaut, et - les builders de fournisseur temps réel. - - OpenRouter utilise `api.js` pour son builder de fournisseur ainsi que pour les helpers - d’intégration/configuration, tandis que `register.runtime.js` peut encore réexporter des helpers génériques +- Séparation des points d’entrée du dépôt : + `/api.js` est le barrel des assistants/types, + `/runtime-api.js` est le barrel réservé à l’exécution, + `/index.js` est l’entrée du plugin bundlé, + et `/setup-entry.js` est l’entrée du plugin de configuration. +- Exemples actuels de fournisseurs bundlés : + - Anthropic utilise `api.js` / `contract-api.js` pour les assistants de flux Claude tels que + `wrapAnthropicProviderStream`, les assistants d’en-têtes bêta et l’analyse de `service_tier`. + - OpenAI utilise `api.js` pour les constructeurs de fournisseurs, les assistants de modèle par défaut et + les constructeurs de fournisseurs temps réel. + - OpenRouter utilise `api.js` pour son constructeur de fournisseur ainsi que ses assistants d’onboarding/de configuration, + tandis que `register.runtime.js` peut toujours réexporter des assistants génériques `plugin-sdk/provider-stream` pour un usage local au dépôt. -- Les points d’entrée publics chargés par façade préfèrent l’instantané actif de configuration runtime - lorsqu’il existe, puis retombent sur le fichier de configuration résolu sur disque lorsqu’OpenClaw ne sert pas encore d’instantané runtime. -- Les primitives partagées génériques restent le contrat public privilégié du SDK. Un petit - ensemble réservé de compatibilité de coutures d’helpers de canal marquées bundled existe encore. Traitez-les comme des coutures de maintenance bundled/compatibilité, et non comme de nouvelles cibles d’import tierces ; les nouveaux contrats inter-canaux doivent toujours être placés sur des sous-chemins génériques `plugin-sdk/*` ou sur les barrels locaux au plugin `api.js` / - `runtime-api.js`. +- Les points d’entrée publics chargés par façade préfèrent l’instantané actif de configuration d’exécution + lorsqu’il en existe un, puis reviennent au fichier de configuration résolu sur disque lorsque + OpenClaw ne sert pas encore d’instantané d’exécution. +- Les primitives génériques partagées restent le contrat public privilégié du SDK. Un petit + ensemble réservé de compatibilité de jonctions d’assistance marquées par canal bundlé existe encore. Traitez-les comme des jonctions de maintenance/compatibilité bundlée, et non comme de nouvelles cibles d’importation tierces ; les nouveaux contrats inter-canaux doivent toujours être ajoutés sur des sous-chemins génériques `plugin-sdk/*` ou sur les barrels locaux `api.js` / + `runtime-api.js` du plugin. -Remarque de compatibilité : +Note de compatibilité : - Évitez le barrel racine `openclaw/plugin-sdk` pour le nouveau code. -- Préférez d’abord les primitives stables et étroites. Les nouveaux sous-chemins de configuration/appairage/réponse/ - feedback/contrat/entrant/threading/commande/secret-input/Webhook/infra/ - allowlist/statut/message-tool constituent le contrat visé pour le nouveau - travail sur les plugins bundled et externes. - L’analyse/la correspondance des cibles appartient à `openclaw/plugin-sdk/channel-targets`. - Les garde-fous d’action de message et les helpers d’id de message de réaction appartiennent à +- Préférez d’abord les primitives stables étroites. Les sous-chemins plus récents pour setup/pairing/reply/ + feedback/contract/inbound/threading/command/secret-input/webhook/infra/ + allowlist/status/message-tool constituent le contrat prévu pour le nouveau + travail de plugin bundlé et externe. + L’analyse/la correspondance des cibles doit se faire sur `openclaw/plugin-sdk/channel-targets`. + Les barrières d’actions de message et les assistants d’id de message pour réactions doivent se trouver sur `openclaw/plugin-sdk/channel-actions`. -- Les barrels d’helpers spécifiques à une extension bundled ne sont pas stables par défaut. Si un - helper n’est nécessaire que pour une extension bundled, gardez-le derrière la couture locale - `api.js` ou `runtime-api.js` de l’extension au lieu de le promouvoir dans +- Les barrels d’assistance spécifiques aux extensions bundlées ne sont pas stables par défaut. Si un + assistant n’est nécessaire que pour une extension bundlée, conservez-le derrière la + jonction locale `api.js` ou `runtime-api.js` de l’extension au lieu de le promouvoir dans `openclaw/plugin-sdk/`. -- Les nouvelles coutures d’helpers partagés doivent être génériques, pas marquées par canal. L’analyse - partagée des cibles appartient à `openclaw/plugin-sdk/channel-targets` ; les internes spécifiques à un canal - restent derrière la couture locale `api.js` ou `runtime-api.js` du plugin propriétaire. -- Les sous-chemins spécifiques à une capacité tels que `image-generation`, - `media-understanding` et `speech` existent parce que les plugins bundled/natifs les utilisent - aujourd’hui. Leur présence ne signifie pas à elle seule que chaque helper exporté est un contrat externe figé à long terme. +- Les nouvelles jonctions d’assistance partagée doivent être génériques, et non marquées par canal. L’analyse + partagée des cibles doit se trouver sur `openclaw/plugin-sdk/channel-targets` ; les éléments internes spécifiques au canal + restent derrière la jonction locale `api.js` ou `runtime-api.js` du plugin propriétaire. +- Des sous-chemins spécifiques à une capacité tels que `image-generation`, + `media-understanding` et `speech` existent parce que les plugins bundlés/natifs les utilisent + aujourd’hui. Leur présence ne signifie pas à elle seule que chaque assistant exporté est un contrat externe gelé à long terme. -## Schémas de l’outil message +## Schémas de l’outil de message -Les plugins doivent posséder les contributions de schéma `describeMessageTool(...)` -spécifiques au canal. Conservez les champs spécifiques au fournisseur dans le plugin, pas dans le cœur partagé. +Les plugins doivent posséder les contributions de schéma `describeMessageTool(...)` spécifiques au canal. +Conservez les champs spécifiques au fournisseur dans le plugin, pas dans le core partagé. -Pour les fragments de schéma portables partagés, réutilisez les helpers génériques exportés via +Pour les fragments de schéma portables partagés, réutilisez les assistants génériques exportés via `openclaw/plugin-sdk/channel-actions` : - `createMessageToolButtonsSchema()` pour les charges utiles de style grille de boutons -- `createMessageToolCardSchema()` pour les charges utiles de carte structurée +- `createMessageToolCardSchema()` pour les charges utiles de cartes structurées -Si une forme de schéma n’a de sens que pour un seul fournisseur, définissez-la dans les -sources propres à ce plugin au lieu de la promouvoir dans le SDK partagé. +Si une forme de schéma n’a de sens que pour un seul fournisseur, définissez-la dans la +propre source de ce plugin au lieu de la promouvoir dans le SDK partagé. -## Résolution de cible de canal +## Résolution des cibles de canal -Les plugins de canal doivent posséder la sémantique des cibles spécifique au canal. Gardez l’hôte sortant partagé -générique et utilisez la surface d’adaptateur de messagerie pour les règles fournisseur : +Les plugins de canal doivent posséder la sémantique des cibles spécifique au canal. Conservez l’hôte +sortant partagé générique et utilisez la surface de l’adaptateur de messagerie pour les règles de fournisseur : - `messaging.inferTargetChatType({ to })` décide si une cible normalisée doit être traitée comme `direct`, `group` ou `channel` avant la recherche dans l’annuaire. -- `messaging.targetResolver.looksLikeId(raw, normalized)` indique au cœur si une +- `messaging.targetResolver.looksLikeId(raw, normalized)` indique au core si une entrée doit passer directement à une résolution de type id au lieu d’une recherche dans l’annuaire. - `messaging.targetResolver.resolveTarget(...)` est le repli du plugin lorsque le - cœur a besoin d’une résolution finale appartenant au fournisseur après normalisation ou après un échec de recherche - dans l’annuaire. -- `messaging.resolveOutboundSessionRoute(...)` possède la construction spécifique au fournisseur de la route de session - sortante une fois une cible résolue. + core a besoin d’une résolution finale appartenant au fournisseur après normalisation ou après + un échec de l’annuaire. +- `messaging.resolveOutboundSessionRoute(...)` possède la construction de route de session spécifique au fournisseur + une fois la cible résolue. Répartition recommandée : -- Utilisez `inferTargetChatType` pour les décisions de catégorie qui doivent être prises avant - la recherche dans les pairs/groupes. -- Utilisez `looksLikeId` pour les vérifications de type « traiter ceci comme un id de cible explicite/natif ». +- Utilisez `inferTargetChatType` pour les décisions de catégorie qui doivent se produire avant + la recherche de pairs/groupes. +- Utilisez `looksLikeId` pour les vérifications du type « traiter ceci comme un id de cible explicite/natif ». - Utilisez `resolveTarget` pour le repli de normalisation spécifique au fournisseur, pas pour une recherche large dans l’annuaire. -- Conservez les ids natifs du fournisseur comme les ids de chat, ids de thread, JID, handles et ids de room - dans les valeurs `target` ou les paramètres spécifiques au fournisseur, et non dans des champs génériques du SDK. +- Conservez les ids natifs du fournisseur comme les ids de chat, ids de thread, JID, handles et ids de salle + dans les valeurs `target` ou dans les paramètres spécifiques au fournisseur, pas dans des champs génériques du SDK. ## Annuaires adossés à la configuration -Les plugins qui dérivent des entrées d’annuaire à partir de la configuration doivent garder cette logique dans le -plugin et réutiliser les helpers partagés de +Les plugins qui dérivent des entrées d’annuaire à partir de la configuration doivent conserver cette logique dans le +plugin et réutiliser les assistants partagés de `openclaw/plugin-sdk/directory-runtime`. -Utilisez cela lorsqu’un canal a besoin de pairs/groupes adossés à la configuration, par exemple : +Utilisez cela lorsqu’un canal a besoin de pairs/groupes adossés à la configuration tels que : -- pairs de message privé pilotés par allowlist -- cartes configurées de canaux/groupes +- pairs de messages directs pilotés par allowlist +- mappages configurés de canaux/groupes - replis d’annuaire statiques à portée de compte -Les helpers partagés de `directory-runtime` ne gèrent que les opérations génériques : +Les assistants partagés de `directory-runtime` ne gèrent que des opérations génériques : - filtrage des requêtes - application des limites -- helpers de déduplication/normalisation +- assistants de déduplication/normalisation - construction de `ChannelDirectoryEntry[]` -L’inspection de compte spécifique au canal et la normalisation d’id doivent rester dans l’implémentation du -plugin. +L’inspection de compte spécifique au canal et la normalisation des ids doivent rester dans +l’implémentation du plugin. ## Catalogues de fournisseurs -Les plugins fournisseurs peuvent définir des catalogues de modèles pour l’inférence avec +Les plugins de fournisseur peuvent définir des catalogues de modèles pour l’inférence avec `registerProvider({ catalog: { run(...) { ... } } })`. `catalog.run(...)` renvoie la même forme que celle qu’OpenClaw écrit dans @@ -1289,7 +1307,8 @@ Les plugins fournisseurs peuvent définir des catalogues de modèles pour l’in - `{ provider }` pour une entrée de fournisseur - `{ providers }` pour plusieurs entrées de fournisseur -Utilisez `catalog` lorsque le plugin possède des ids de modèle spécifiques au fournisseur, des valeurs par défaut de base URL, ou des métadonnées de modèle protégées par authentification. +Utilisez `catalog` lorsque le plugin possède les ids de modèle spécifiques au fournisseur, les valeurs par défaut d’URL de base +ou des métadonnées de modèle protégées par authentification. `catalog.order` contrôle le moment où le catalogue d’un plugin fusionne par rapport aux fournisseurs implicites intégrés d’OpenClaw : @@ -1299,43 +1318,47 @@ fournisseurs implicites intégrés d’OpenClaw : - `paired` : fournisseurs qui synthétisent plusieurs entrées de fournisseur liées - `late` : dernier passage, après les autres fournisseurs implicites -Les fournisseurs plus tardifs l’emportent en cas de collision de clé, donc les plugins peuvent intentionnellement remplacer une entrée de fournisseur intégrée avec le même id de fournisseur. +Les fournisseurs ultérieurs l’emportent en cas de collision de clé, de sorte que les plugins peuvent +remplacer intentionnellement une entrée de fournisseur intégrée avec le même id de fournisseur. Compatibilité : -- `discovery` fonctionne toujours comme alias legacy +- `discovery` fonctionne toujours comme alias hérité - si `catalog` et `discovery` sont tous deux enregistrés, OpenClaw utilise `catalog` -## Inspection en lecture seule des canaux +## Inspection de canal en lecture seule -Si votre plugin enregistre un canal, préférez l’implémentation de -`plugin.config.inspectAccount(cfg, accountId)` en complément de `resolveAccount(...)`. +Si votre plugin enregistre un canal, préférez implémenter +`plugin.config.inspectAccount(cfg, accountId)` en parallèle de `resolveAccount(...)`. Pourquoi : -- `resolveAccount(...)` est le chemin runtime. Il peut supposer que les identifiants - sont entièrement matérialisés et peut échouer rapidement lorsque les secrets requis sont absents. +- `resolveAccount(...)` est le chemin d’exécution. Il peut supposer que les identifiants + sont entièrement matérialisés et échouer rapidement lorsque des secrets requis sont absents. - Les chemins de commande en lecture seule tels que `openclaw status`, `openclaw status --all`, - `openclaw channels status`, `openclaw channels resolve`, et les flux doctor/réparation - de configuration ne devraient pas avoir besoin de matérialiser les identifiants runtime juste pour + `openclaw channels status`, `openclaw channels resolve` et les flux doctor/réparation de configuration + ne doivent pas avoir besoin de matérialiser les identifiants d’exécution simplement pour décrire la configuration. Comportement recommandé pour `inspectAccount(...)` : -- Retournez uniquement un état descriptif du compte. -- Préservez `enabled` et `configured`. -- Incluez les champs source/statut des identifiants lorsque c’est pertinent, par exemple : +- Renvoyer uniquement un état descriptif du compte. +- Préserver `enabled` et `configured`. +- Inclure les champs de source/statut d’identifiants lorsque c’est pertinent, tels que : - `tokenSource`, `tokenStatus` - `botTokenSource`, `botTokenStatus` - `appTokenSource`, `appTokenStatus` - `signingSecretSource`, `signingSecretStatus` -- Vous n’avez pas besoin de renvoyer les valeurs brutes des jetons simplement pour signaler une disponibilité en lecture seule. Renvoyer `tokenStatus: "available"` (et le champ source correspondant) suffit pour des commandes de type statut. -- Utilisez `configured_unavailable` lorsqu’un identifiant est configuré via SecretRef mais indisponible dans le chemin de commande courant. +- Vous n’avez pas besoin de renvoyer les valeurs brutes des jetons simplement pour signaler une + disponibilité en lecture seule. Renvoyer `tokenStatus: "available"` (ainsi que le champ de source correspondant) + suffit pour les commandes de type status. +- Utilisez `configured_unavailable` lorsqu’un identifiant est configuré via SecretRef mais + indisponible dans le chemin de commande courant. -Cela permet aux commandes en lecture seule d’indiquer « configuré mais indisponible dans ce chemin de commande » -au lieu de planter ou de signaler à tort que le compte n’est pas configuré. +Cela permet aux commandes en lecture seule de signaler « configuré mais indisponible dans ce chemin de commande » +au lieu de planter ou d’indiquer à tort que le compte n’est pas configuré. -## Packs de paquets +## Packs de packages Un répertoire de plugin peut inclure un `package.json` avec `openclaw.extensions` : @@ -1355,53 +1378,60 @@ devient `name/`. Si votre plugin importe des dépendances npm, installez-les dans ce répertoire afin que `node_modules` soit disponible (`npm install` / `pnpm install`). -Garde-fou de sécurité : chaque entrée `openclaw.extensions` doit rester dans le répertoire du plugin -après résolution des liens symboliques. Les entrées qui sortent du répertoire du paquet sont +Garde-fou de sécurité : chaque entrée `openclaw.extensions` doit rester à l’intérieur du répertoire du plugin +après résolution des liens symboliques. Les entrées qui sortent du répertoire du package sont rejetées. Note de sécurité : `openclaw plugins install` installe les dépendances du plugin avec -`npm install --omit=dev --ignore-scripts` (pas de scripts de cycle de vie, pas de dépendances de développement à l’exécution). Gardez les arbres de dépendances de plugin en « JS/TS pur » et évitez les paquets qui nécessitent des builds `postinstall`. +`npm install --omit=dev --ignore-scripts` (pas de scripts de cycle de vie, pas de dépendances de développement à l’exécution). Conservez les arbres de dépendances du plugin en +« pur JS/TS » et évitez les packages qui nécessitent des builds `postinstall`. Facultatif : `openclaw.setupEntry` peut pointer vers un module léger réservé à la configuration. -Lorsque OpenClaw a besoin des surfaces de configuration pour un plugin de canal désactivé, ou -lorsqu’un plugin de canal est activé mais pas encore configuré, il charge `setupEntry` -au lieu du point d’entrée complet du plugin. Cela allège le démarrage et la configuration -lorsque votre point d’entrée principal câble aussi des outils, hooks ou autre code réservé au runtime. +Lorsqu’OpenClaw a besoin des surfaces de configuration pour un plugin de canal désactivé, ou +lorsqu’un plugin de canal est activé mais encore non configuré, il charge `setupEntry` +au lieu de l’entrée complète du plugin. Cela allège le démarrage et la configuration +lorsque l’entrée principale de votre plugin câble aussi des outils, des hooks ou d’autres +éléments réservés à l’exécution. Facultatif : `openclaw.startup.deferConfiguredChannelFullLoadUntilAfterListen` -peut faire entrer un plugin de canal dans le même chemin `setupEntry` pendant la phase de -démarrage pré-écoute de la gateway, même lorsque le canal est déjà configuré. +peut faire opter un plugin de canal pour ce même chemin `setupEntry` pendant la +phase de démarrage pré-écoute de la gateway, même lorsque le canal est déjà configuré. -N’utilisez cela que si `setupEntry` couvre entièrement la surface de démarrage qui doit exister -avant que la gateway commence à écouter. En pratique, cela signifie que le point d’entrée de configuration -doit enregistrer toutes les capacités appartenant au canal dont le démarrage dépend, telles que : +Utilisez cela uniquement lorsque `setupEntry` couvre entièrement la surface de démarrage qui doit exister +avant que la gateway ne commence à écouter. En pratique, cela signifie que l’entrée de configuration +doit enregistrer chaque capacité appartenant au canal dont le démarrage dépend, comme : - l’enregistrement du canal lui-même -- toute route HTTP devant être disponible avant que la gateway commence à écouter -- toutes méthodes Gateway, outils ou services qui doivent exister pendant cette même fenêtre +- toute route HTTP qui doit être disponible avant que la gateway ne commence à écouter +- toute méthode Gateway, tout outil ou tout service qui doit exister pendant cette même fenêtre -Si votre point d’entrée complet possède encore une capacité de démarrage requise, n’activez pas -ce drapeau. Conservez le comportement par défaut du plugin et laissez OpenClaw charger le point d’entrée complet au démarrage. +Si votre entrée complète possède encore une capacité de démarrage requise, n’activez pas +ce drapeau. Conservez le comportement par défaut du plugin et laissez OpenClaw charger +l’entrée complète pendant le démarrage. -Les canaux bundled peuvent aussi publier des helpers de surface de contrat réservés à la configuration que le cœur -peut consulter avant que le runtime complet du canal ne soit chargé. La surface actuelle de promotion de configuration est : +Les canaux bundlés peuvent également publier des assistants de surface de contrat réservés à la configuration que le core +peut consulter avant que le runtime complet du canal soit chargé. La surface actuelle de +promotion de configuration est : - `singleAccountKeysToMove` - `namedAccountPromotionKeys` - `resolveSingleAccountPromotionTarget(...)` -Le cœur utilise cette surface lorsqu’il doit promouvoir une configuration legacy de canal à compte unique -dans `channels..accounts.*` sans charger le point d’entrée complet du plugin. -Matrix est l’exemple bundled actuel : il ne déplace que les clés d’authentification/bootstrap dans un -compte promu nommé lorsque des comptes nommés existent déjà, et il peut préserver une clé de compte par défaut non canonique configurée au lieu de toujours créer +Le core utilise cette surface lorsqu’il a besoin de promouvoir une configuration héritée de canal à compte unique +dans `channels..accounts.*` sans charger l’entrée complète du plugin. +Matrix est l’exemple bundlé actuel : il déplace uniquement les clés d’authentification/d’amorçage dans un +compte promu nommé lorsque des comptes nommés existent déjà, et il peut préserver une +clé de compte par défaut configurée non canonique au lieu de toujours créer `accounts.default`. -Ces adaptateurs de patch de configuration gardent la découverte de la surface de contrat bundled paresseuse. Le temps d’import reste léger ; la surface de promotion n’est chargée qu’au premier usage au lieu de réentrer dans le démarrage du canal bundled lors de l’import du module. +Ces adaptateurs de patch de configuration maintiennent la découverte paresseuse de la surface de contrat bundlée. Le temps +d’importation reste léger ; la surface de promotion n’est chargée qu’au premier usage au lieu +de réentrer dans le démarrage du canal bundlé lors de l’importation du module. -Lorsque ces surfaces de démarrage incluent des méthodes RPC Gateway, gardez-les sur un préfixe -spécifique au plugin. Les espaces de noms d’administration du cœur (`config.*`, +Lorsque ces surfaces de démarrage incluent des méthodes RPC Gateway, conservez-les sur un +préfixe spécifique au plugin. Les espaces de noms d’administration du core (`config.*`, `exec.approvals.*`, `wizard.*`, `update.*`) restent réservés et se résolvent toujours -vers `operator.admin`, même si un plugin demande une portée plus étroite. +en `operator.admin`, même si un plugin demande une portée plus étroite. Exemple : @@ -1420,8 +1450,8 @@ Exemple : ### Métadonnées de catalogue de canal -Les plugins de canal peuvent annoncer des métadonnées de configuration/découverte via `openclaw.channel` et -des indications d’installation via `openclaw.install`. Cela garde les données du catalogue de cœur vides. +Les plugins de canal peuvent publier des métadonnées de configuration/découverte via `openclaw.channel` et +des indications d’installation via `openclaw.install`. Cela permet au catalogue du core de rester sans données. Exemple : @@ -1436,7 +1466,7 @@ Exemple : "selectionLabel": "Nextcloud Talk (self-hosted)", "docsPath": "/channels/nextcloud-talk", "docsLabel": "nextcloud-talk", - "blurb": "Self-hosted chat via Nextcloud Talk webhook bots.", + "blurb": "Chat auto-hébergé via des bots Webhook Nextcloud Talk.", "order": 65, "aliases": ["nc-talk", "nc"] }, @@ -1451,20 +1481,21 @@ Exemple : Champs utiles de `openclaw.channel` au-delà de l’exemple minimal : -- `detailLabel` : libellé secondaire pour des surfaces de catalogue/statut plus riches +- `detailLabel` : libellé secondaire pour des surfaces de catalogue/de statut plus riches - `docsLabel` : remplace le texte du lien vers la documentation -- `preferOver` : ids de plugin/canal de priorité plus basse que cette entrée de catalogue doit dépasser +- `preferOver` : ids de plugin/canal de priorité inférieure que cette entrée de catalogue doit dépasser - `selectionDocsPrefix`, `selectionDocsOmitLabel`, `selectionExtras` : contrôles de copie de la surface de sélection -- `markdownCapable` : marque le canal comme compatible Markdown pour les décisions de formatage sortant -- `exposure.configured` : masque le canal des surfaces de liste de canaux configurés lorsqu’il est défini à `false` -- `exposure.setup` : masque le canal des sélecteurs interactifs de configuration lorsque défini à `false` -- `exposure.docs` : marque le canal comme interne/privé pour les surfaces de navigation documentaire -- `showConfigured` / `showInSetup` : alias legacy toujours acceptés pour compatibilité ; préférez `exposure` -- `quickstartAllowFrom` : fait entrer le canal dans le flux standard `allowFrom` du démarrage rapide -- `forceAccountBinding` : exige une liaison explicite de compte même lorsqu’un seul compte existe +- `markdownCapable` : marque le canal comme compatible markdown pour les décisions de formatage sortant +- `exposure.configured` : masque le canal des surfaces de liste de canaux configurés lorsqu’il vaut `false` +- `exposure.setup` : masque le canal des sélecteurs interactifs de configuration lorsqu’il vaut `false` +- `exposure.docs` : marque le canal comme interne/privé pour les surfaces de navigation de documentation +- `showConfigured` / `showInSetup` : alias hérités toujours acceptés pour compatibilité ; préférez `exposure` +- `quickstartAllowFrom` : fait opter le canal pour le flux standard `allowFrom` de démarrage rapide +- `forceAccountBinding` : exige une liaison de compte explicite même lorsqu’un seul compte existe - `preferSessionLookupForAnnounceTarget` : préfère la recherche de session lors de la résolution des cibles d’annonce -OpenClaw peut aussi fusionner des **catalogues de canaux externes** (par exemple, une exportation de registre MPM). Déposez un fichier JSON à l’un des emplacements suivants : +OpenClaw peut aussi fusionner des **catalogues de canaux externes** (par exemple, une +exportation de registre MPM). Déposez un fichier JSON à l’un de ces emplacements : - `~/.openclaw/mpm/plugins.json` - `~/.openclaw/mpm/catalog.json` @@ -1472,12 +1503,12 @@ OpenClaw peut aussi fusionner des **catalogues de canaux externes** (par exemple Ou faites pointer `OPENCLAW_PLUGIN_CATALOG_PATHS` (ou `OPENCLAW_MPM_CATALOG_PATHS`) vers un ou plusieurs fichiers JSON (délimités par virgule/point-virgule/`PATH`). Chaque fichier doit -contenir `{ "entries": [ { "name": "@scope/pkg", "openclaw": { "channel": {...}, "install": {...} } } ] }`. L’analyseur accepte aussi `"packages"` ou `"plugins"` comme alias legacy pour la clé `"entries"`. +contenir `{ "entries": [ { "name": "@scope/pkg", "openclaw": { "channel": {...}, "install": {...} } } ] }`. L’analyseur accepte aussi `"packages"` ou `"plugins"` comme alias hérités pour la clé `"entries"`. ## Plugins de moteur de contexte Les plugins de moteur de contexte possèdent l’orchestration du contexte de session pour l’ingestion, l’assemblage -et la compaction. Enregistrez-les depuis votre plugin avec +et la Compaction. Enregistrez-les depuis votre plugin avec `api.registerContextEngine(id, factory)`, puis sélectionnez le moteur actif avec `plugins.slots.contextEngine`. @@ -1510,7 +1541,7 @@ export default function (api) { } ``` -Si votre moteur ne possède **pas** l’algorithme de compaction, gardez `compact()` +Si votre moteur ne possède **pas** l’algorithme de Compaction, laissez `compact()` implémenté et déléguez-le explicitement : ```ts @@ -1549,40 +1580,41 @@ export default function (api) { ## Ajouter une nouvelle capacité Lorsqu’un plugin a besoin d’un comportement qui ne correspond pas à l’API actuelle, ne contournez pas -le système de plugins avec un accès privé. Ajoutez la capacité manquante. +le système de plugins par un accès privé direct. Ajoutez la capacité manquante. Séquence recommandée : -1. définir le contrat du cœur - Décidez quel comportement partagé le cœur doit posséder : politique, repli, fusion de configuration, - cycle de vie, sémantique orientée canal, et forme du helper runtime. -2. ajouter des surfaces typées d’enregistrement/runtime de plugin - Étendez `OpenClawPluginApi` et/ou `api.runtime` avec la plus petite surface de capacité typée utile. -3. raccorder les consommateurs cœur + canal/fonctionnalité - Les canaux et plugins de fonctionnalité doivent consommer la nouvelle capacité via le cœur, +1. définir le contrat du core + Décidez quel comportement partagé le core doit posséder : politique, repli, fusion de configuration, + cycle de vie, sémantique orientée canal et forme de l’assistant d’exécution. +2. ajouter des surfaces typées d’enregistrement/de runtime de plugin + Étendez `OpenClawPluginApi` et/ou `api.runtime` avec la plus petite + surface de capacité typée utile. +3. relier les consommateurs du core + du canal/de la fonctionnalité + Les canaux et plugins de fonctionnalité doivent consommer la nouvelle capacité via le core, et non en important directement une implémentation fournisseur. 4. enregistrer les implémentations fournisseur - Les plugins fournisseurs enregistrent ensuite leurs backends sur la capacité. + Les plugins fournisseurs enregistrent ensuite leurs backends sur cette capacité. 5. ajouter une couverture de contrat - Ajoutez des tests afin que la responsabilité et la forme d’enregistrement restent explicites dans le temps. + Ajoutez des tests afin que la propriété et la forme d’enregistrement restent explicites dans le temps. -C’est ainsi qu’OpenClaw reste affirmé sans devenir codé en dur selon la vision du monde d’un -seul fournisseur. Voir le [Capability Cookbook](/fr/plugins/architecture) -pour une checklist concrète de fichiers et un exemple détaillé. +C’est ainsi qu’OpenClaw reste prescriptif sans devenir codé en dur selon la +vision du monde d’un seul fournisseur. Voir le [Recueil de recettes des capacités](/fr/plugins/architecture) +pour une checklist de fichiers concrète et un exemple détaillé. ### Checklist de capacité -Lorsque vous ajoutez une nouvelle capacité, l’implémentation doit généralement toucher ces -surfaces ensemble : +Lorsque vous ajoutez une nouvelle capacité, l’implémentation doit généralement toucher +ces surfaces ensemble : -- types de contrat du cœur dans `src//types.ts` -- helper runner/runtime du cœur dans `src//runtime.ts` -- surface d’enregistrement de l’API des plugins dans `src/plugins/types.ts` -- câblage du registre de plugins dans `src/plugins/registry.ts` -- exposition runtime du plugin dans `src/plugins/runtime/*` lorsque les plugins de fonctionnalité/canal +- types de contrat du core dans `src//types.ts` +- assistant d’exécution/exécuteur du core dans `src//runtime.ts` +- surface d’enregistrement de l’API de plugin dans `src/plugins/types.ts` +- câblage du registre des plugins dans `src/plugins/registry.ts` +- exposition du runtime de plugin dans `src/plugins/runtime/*` lorsque des plugins de fonctionnalité/canal doivent la consommer -- helpers de capture/test dans `src/test-utils/plugin-registration.ts` -- assertions de responsabilité/contrat dans `src/plugins/contracts/registry.ts` +- assistants de capture/test dans `src/test-utils/plugin-registration.ts` +- assertions de propriété/de contrat dans `src/plugins/contracts/registry.ts` - documentation opérateur/plugin dans `docs/` Si l’une de ces surfaces manque, c’est généralement le signe que la capacité n’est @@ -1593,14 +1625,14 @@ pas encore entièrement intégrée. Modèle minimal : ```ts -// core contract +// contrat du core export type VideoGenerationProviderPlugin = { id: string; label: string; generateVideo: (req: VideoGenerationRequest) => Promise; }; -// plugin API +// API de plugin api.registerVideoGenerationProvider({ id: "openai", label: "OpenAI", @@ -1609,7 +1641,7 @@ api.registerVideoGenerationProvider({ }, }); -// shared runtime helper for feature/channel plugins +// assistant d’exécution partagé pour les plugins de fonctionnalité/canal const clip = await api.runtime.videoGeneration.generate({ prompt: "Show the robot walking through the lab.", cfg, @@ -1624,7 +1656,7 @@ expect(findVideoGenerationProviderIdsForPlugin("openai")).toEqual(["openai"]); Cela garde la règle simple : -- le cœur possède le contrat de capacité + l’orchestration +- le core possède le contrat de capacité + l’orchestration - les plugins fournisseurs possèdent les implémentations fournisseur -- les plugins de fonctionnalité/canal consomment les helpers runtime -- les tests de contrat gardent la responsabilité explicite +- les plugins de fonctionnalité/canal consomment les assistants d’exécution +- les tests de contrat gardent la propriété explicite diff --git a/docs/fr/plugins/manifest.md b/docs/fr/plugins/manifest.md index 511cb20ac..65ddbc2be 100644 --- a/docs/fr/plugins/manifest.md +++ b/docs/fr/plugins/manifest.md @@ -1,75 +1,74 @@ --- read_when: - Vous créez un Plugin OpenClaw - - Vous devez livrer un schéma de configuration de Plugin ou déboguer des erreurs de validation de Plugin -summary: Manifeste de Plugin + exigences du schéma JSON (validation stricte de la configuration) -title: Manifeste de Plugin + - Vous devez livrer un schéma de configuration du Plugin ou déboguer les erreurs de validation du Plugin +summary: Exigences du manifeste du Plugin + schéma JSON (validation stricte de la configuration) +title: Manifeste du Plugin x-i18n: - generated_at: "2026-04-12T23:28:44Z" + generated_at: "2026-04-15T06:56:44Z" model: gpt-5.4 provider: openai - source_hash: 93b57c7373e4ccd521b10945346db67991543bd2bed4cc8b6641e1f215b48579 + source_hash: ba2183bfa8802871e4ef33a0ebea290606e8351e9e83e25ee72456addb768730 source_path: plugins/manifest.md workflow: 15 --- -# Manifeste de Plugin (`openclaw.plugin.json`) +# Manifeste du Plugin (`openclaw.plugin.json`) -Cette page concerne uniquement le **manifeste de Plugin natif OpenClaw**. +Cette page concerne uniquement le **manifeste natif de Plugin OpenClaw**. -Pour les formats de bundles compatibles, voir [Plugin bundles](/fr/plugins/bundles). +Pour les dispositions de bundle compatibles, consultez [Plugin bundles](/fr/plugins/bundles). -Les formats de bundle compatibles utilisent des fichiers de manifeste différents : +Les formats de bundle compatibles utilisent des fichiers de manifeste différents : -- Bundle Codex : `.codex-plugin/plugin.json` -- Bundle Claude : `.claude-plugin/plugin.json` ou la disposition par défaut des composants Claude - sans manifeste -- Bundle Cursor : `.cursor-plugin/plugin.json` +- Bundle Codex : `.codex-plugin/plugin.json` +- Bundle Claude : `.claude-plugin/plugin.json` ou la disposition de composant Claude + par défaut sans manifeste +- Bundle Cursor : `.cursor-plugin/plugin.json` OpenClaw détecte automatiquement ces dispositions de bundle également, mais elles ne sont pas validées par rapport au schéma `openclaw.plugin.json` décrit ici. Pour les bundles compatibles, OpenClaw lit actuellement les métadonnées du bundle ainsi que les racines de -Skills déclarées, les racines de commandes Claude, les valeurs par défaut `settings.json` des bundles Claude, -les valeurs par défaut LSP des bundles Claude, et les packs de hooks pris en charge lorsque la disposition correspond -aux attentes du runtime OpenClaw. +Skills déclarées, les racines de commandes Claude, les valeurs par défaut de `settings.json` du bundle Claude, +les valeurs par défaut LSP du bundle Claude, et les packs de hooks pris en charge lorsque la disposition correspond +aux attentes d’exécution d’OpenClaw. -Chaque Plugin natif OpenClaw **doit** fournir un fichier `openclaw.plugin.json` à la +Chaque Plugin OpenClaw natif **doit** fournir un fichier `openclaw.plugin.json` dans la **racine du Plugin**. OpenClaw utilise ce manifeste pour valider la configuration -**sans exécuter le code du Plugin**. Les manifestes manquants ou invalides sont traités comme +**sans exécuter le code du Plugin**. Les manifestes absents ou invalides sont traités comme des erreurs de Plugin et bloquent la validation de la configuration. -Voir le guide complet du système de Plugins : [Plugins](/fr/tools/plugin). -Pour le modèle natif de capacités et les recommandations actuelles de compatibilité externe : -[Capability model](/fr/plugins/architecture#public-capability-model). +Consultez le guide complet du système de Plugin : [Plugins](/fr/tools/plugin). +Pour le modèle natif de capacités et les recommandations actuelles de compatibilité externe : +[Modèle de capacités](/fr/plugins/architecture#public-capability-model). -## Rôle de ce fichier +## À quoi sert ce fichier -`openclaw.plugin.json` correspond aux métadonnées qu’OpenClaw lit avant de charger le +`openclaw.plugin.json` est la métadonnée qu’OpenClaw lit avant de charger le code de votre Plugin. -Utilisez-le pour : +Utilisez-le pour : - l’identité du Plugin - la validation de la configuration -- les métadonnées d’authentification et d’onboarding qui doivent être disponibles sans démarrer le runtime du Plugin -- les indications d’activation peu coûteuses que les surfaces du plan de contrôle peuvent inspecter avant le chargement du runtime -- les descripteurs de configuration peu coûteux que les surfaces de configuration/onboarding peuvent inspecter avant le chargement du runtime -- les métadonnées d’alias et d’activation automatique qui doivent être résolues avant le chargement du runtime du Plugin -- les métadonnées abrégées de propriété de famille de modèles qui doivent auto-activer le - Plugin avant le chargement du runtime -- les instantanés statiques de propriété de capacités utilisés pour le câblage de compatibilité intégré et la couverture des contrats -- les métadonnées de configuration spécifiques aux canaux qui doivent être fusionnées dans les surfaces de catalogue et de validation - sans charger le runtime -- les indications d’interface utilisateur pour la configuration +- les métadonnées d’authentification et d’onboarding qui doivent être disponibles sans démarrer l’environnement d’exécution du Plugin +- les indications d’activation peu coûteuses que les surfaces du plan de contrôle peuvent inspecter avant le chargement de l’environnement d’exécution +- les descripteurs de configuration peu coûteux que les surfaces de configuration/onboarding peuvent inspecter avant le chargement de l’environnement d’exécution +- les métadonnées d’alias et d’activation automatique qui doivent être résolues avant le chargement de l’environnement d’exécution du Plugin +- les métadonnées abrégées de propriété de famille de modèles qui doivent auto-activer le Plugin avant le chargement de l’environnement d’exécution +- les instantanés statiques de propriété des capacités utilisés pour le câblage de compatibilité intégré et la couverture des contrats +- les métadonnées peu coûteuses de l’exécuteur QA que l’hôte partagé `openclaw qa` peut inspecter avant le chargement de l’environnement d’exécution du Plugin +- les métadonnées de configuration spécifiques aux canaux qui doivent être fusionnées dans les surfaces de catalogue et de validation sans charger l’environnement d’exécution +- les indications d’interface pour la configuration -Ne l’utilisez pas pour : +Ne l’utilisez pas pour : -- enregistrer le comportement du runtime +- enregistrer un comportement d’exécution - déclarer des points d’entrée de code - les métadonnées d’installation npm -Ces éléments relèvent de votre code de Plugin et de `package.json`. +Ces éléments appartiennent à votre code de Plugin et à `package.json`. ## Exemple minimal @@ -84,7 +83,7 @@ Ces éléments relèvent de votre code de Plugin et de `package.json`. } ``` -## Exemple enrichi +## Exemple complet ```json { @@ -111,19 +110,19 @@ Ces éléments relèvent de votre code de Plugin et de `package.json`. "provider": "openrouter", "method": "api-key", "choiceId": "openrouter-api-key", - "choiceLabel": "Clé d’API OpenRouter", + "choiceLabel": "Clé API OpenRouter", "groupId": "openrouter", "groupLabel": "OpenRouter", "optionKey": "openrouterApiKey", "cliFlag": "--openrouter-api-key", "cliOption": "--openrouter-api-key ", - "cliDescription": "Clé d’API OpenRouter", + "cliDescription": "Clé API OpenRouter", "onboardingScopes": ["text-inference"] } ], "uiHints": { "apiKey": { - "label": "Clé d’API", + "label": "Clé API", "placeholder": "sk-or-v1-...", "sensitive": true } @@ -140,64 +139,65 @@ Ces éléments relèvent de votre code de Plugin et de `package.json`. } ``` -## Référence des champs de premier niveau +## Référence des champs de niveau supérieur -| Field | Required | Type | What it means | -| ----------------------------------- | -------- | -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| `id` | Yes | `string` | ID canonique du Plugin. Il s’agit de l’ID utilisé dans `plugins.entries.`. | -| `configSchema` | Yes | `object` | Schéma JSON inline pour la configuration de ce Plugin. | -| `enabledByDefault` | No | `true` | Marque un Plugin intégré comme activé par défaut. Omettez-le, ou définissez toute valeur autre que `true`, pour laisser le Plugin désactivé par défaut. | -| `legacyPluginIds` | No | `string[]` | IDs hérités qui se normalisent vers cet ID canonique de Plugin. | -| `autoEnableWhenConfiguredProviders` | No | `string[]` | IDs de fournisseurs qui doivent auto-activer ce Plugin lorsque l’authentification, la configuration ou les références de modèle les mentionnent. | -| `kind` | No | `"memory"` \| `"context-engine"` | Déclare un type de Plugin exclusif utilisé par `plugins.slots.*`. | -| `channels` | No | `string[]` | IDs de canaux détenus par ce Plugin. Utilisés pour la découverte et la validation de configuration. | -| `providers` | No | `string[]` | IDs de fournisseurs détenus par ce Plugin. | -| `modelSupport` | No | `object` | Métadonnées abrégées, détenues par le manifeste, sur les familles de modèles, utilisées pour charger automatiquement le Plugin avant le runtime. | -| `cliBackends` | No | `string[]` | IDs de backends d’inférence CLI détenus par ce Plugin. Utilisés pour l’auto-activation au démarrage à partir de références de configuration explicites. | -| `commandAliases` | No | `object[]` | Noms de commandes détenus par ce Plugin qui doivent produire une configuration sensible au Plugin et des diagnostics CLI avant le chargement du runtime. | -| `providerAuthEnvVars` | No | `Record` | Métadonnées d’environnement d’authentification fournisseur peu coûteuses qu’OpenClaw peut inspecter sans charger le code du Plugin. | -| `providerAuthAliases` | No | `Record` | IDs de fournisseurs qui doivent réutiliser un autre ID de fournisseur pour la recherche d’authentification, par exemple un fournisseur de code qui partage la clé d’API et les profils d’authentification du fournisseur de base. | -| `channelEnvVars` | No | `Record` | Métadonnées d’environnement de canal peu coûteuses qu’OpenClaw peut inspecter sans charger le code du Plugin. Utilisez-les pour les surfaces de configuration ou d’authentification de canaux pilotées par l’environnement que les helpers génériques de démarrage/configuration doivent voir. | -| `providerAuthChoices` | No | `object[]` | Métadonnées de choix d’authentification peu coûteuses pour les sélecteurs d’onboarding, la résolution du fournisseur préféré et le câblage simple des flags CLI. | -| `activation` | No | `object` | Indications d’activation peu coûteuses pour le chargement déclenché par fournisseur, commande, canal, route et capacité. Métadonnées uniquement ; le runtime du Plugin reste propriétaire du comportement réel. | -| `setup` | No | `object` | Descripteurs de configuration/onboarding peu coûteux que les surfaces de découverte et de configuration peuvent inspecter sans charger le runtime du Plugin. | -| `contracts` | No | `object` | Instantané statique des capacités intégrées pour la parole, la transcription temps réel, la voix temps réel, la compréhension des médias, la génération d’images, la génération musicale, la génération vidéo, la récupération web, la recherche web et la propriété des outils. | -| `channelConfigs` | No | `Record` | Métadonnées de configuration de canal détenues par le manifeste, fusionnées dans les surfaces de découverte et de validation avant le chargement du runtime. | -| `skills` | No | `string[]` | Répertoires de Skills à charger, relatifs à la racine du Plugin. | -| `name` | No | `string` | Nom de Plugin lisible par un humain. | -| `description` | No | `string` | Bref résumé affiché dans les surfaces du Plugin. | -| `version` | No | `string` | Version informative du Plugin. | -| `uiHints` | No | `Record` | Libellés d’interface, placeholders et indications de sensibilité pour les champs de configuration. | +| Champ | Obligatoire | Type | Signification | +| ----------------------------------- | ----------- | -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `id` | Oui | `string` | ID canonique du Plugin. C’est l’ID utilisé dans `plugins.entries.`. | +| `configSchema` | Oui | `object` | Schéma JSON inline pour la configuration de ce Plugin. | +| `enabledByDefault` | Non | `true` | Marque un Plugin intégré comme activé par défaut. Omettez-le, ou définissez une valeur autre que `true`, pour laisser le Plugin désactivé par défaut. | +| `legacyPluginIds` | Non | `string[]` | IDs hérités qui se normalisent vers cet ID canonique de Plugin. | +| `autoEnableWhenConfiguredProviders` | Non | `string[]` | IDs de fournisseurs qui doivent auto-activer ce Plugin lorsque l’authentification, la configuration ou les références de modèles les mentionnent. | +| `kind` | Non | `"memory"` \| `"context-engine"` | Déclare un type exclusif de Plugin utilisé par `plugins.slots.*`. | +| `channels` | Non | `string[]` | IDs de canaux détenus par ce Plugin. Utilisés pour la découverte et la validation de la configuration. | +| `providers` | Non | `string[]` | IDs de fournisseurs détenus par ce Plugin. | +| `modelSupport` | Non | `object` | Métadonnées abrégées de famille de modèles détenues par le manifeste et utilisées pour charger automatiquement le Plugin avant l’environnement d’exécution. | +| `cliBackends` | Non | `string[]` | IDs de backend d’inférence CLI détenus par ce Plugin. Utilisés pour l’auto-activation au démarrage à partir de références de configuration explicites. | +| `commandAliases` | Non | `object[]` | Noms de commandes détenus par ce Plugin qui doivent produire une configuration et des diagnostics CLI tenant compte du Plugin avant le chargement de l’environnement d’exécution. | +| `providerAuthEnvVars` | Non | `Record` | Métadonnées d’environnement d’authentification du fournisseur, peu coûteuses, qu’OpenClaw peut inspecter sans charger le code du Plugin. | +| `providerAuthAliases` | Non | `Record` | IDs de fournisseurs qui doivent réutiliser un autre ID de fournisseur pour la recherche d’authentification, par exemple un fournisseur de codage qui partage la clé API et les profils d’authentification du fournisseur de base. | +| `channelEnvVars` | Non | `Record` | Métadonnées d’environnement de canal, peu coûteuses, qu’OpenClaw peut inspecter sans charger le code du Plugin. Utilisez ceci pour les surfaces de configuration ou d’authentification de canal pilotées par l’environnement que les helpers génériques de démarrage/configuration doivent voir. | +| `providerAuthChoices` | Non | `object[]` | Métadonnées de choix d’authentification peu coûteuses pour les sélecteurs d’onboarding, la résolution du fournisseur préféré et le câblage simple des flags CLI. | +| `activation` | Non | `object` | Indications d’activation peu coûteuses pour le chargement déclenché par des fournisseurs, commandes, canaux, routes et capacités. Métadonnées uniquement ; l’environnement d’exécution du Plugin reste responsable du comportement réel. | +| `setup` | Non | `object` | Descripteurs de configuration/onboarding peu coûteux que les surfaces de découverte et de configuration peuvent inspecter sans charger l’environnement d’exécution du Plugin. | +| `qaRunners` | Non | `object[]` | Descripteurs d’exécuteurs QA peu coûteux utilisés par l’hôte partagé `openclaw qa` avant le chargement de l’environnement d’exécution du Plugin. | +| `contracts` | Non | `object` | Instantané statique des capacités intégrées pour la parole, la transcription en temps réel, la voix en temps réel, la compréhension des médias, la génération d’images, la génération de musique, la génération de vidéo, la récupération web, la recherche web et la propriété des outils. | +| `channelConfigs` | Non | `Record` | Métadonnées de configuration de canal détenues par le manifeste et fusionnées dans les surfaces de découverte et de validation avant le chargement de l’environnement d’exécution. | +| `skills` | Non | `string[]` | Répertoires de Skills à charger, relatifs à la racine du Plugin. | +| `name` | Non | `string` | Nom lisible du Plugin. | +| `description` | Non | `string` | Résumé court affiché dans les surfaces du Plugin. | +| `version` | Non | `string` | Version informative du Plugin. | +| `uiHints` | Non | `Record` | Libellés d’interface, espaces réservés et indications de sensibilité pour les champs de configuration. | -## Référence `providerAuthChoices` +## Référence de `providerAuthChoices` -Chaque entrée `providerAuthChoices` décrit un choix d’onboarding ou d’authentification. -OpenClaw lit cela avant le chargement du runtime du fournisseur. +Chaque entrée de `providerAuthChoices` décrit un choix d’onboarding ou d’authentification. +OpenClaw lit cela avant le chargement de l’environnement d’exécution du fournisseur. -| Champ | Obligatoire | Type | Ce que cela signifie | -| --------------------- | ----------- | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------ | -| `provider` | Oui | `string` | ID du fournisseur auquel ce choix appartient. | -| `method` | Oui | `string` | ID de méthode d’authentification vers lequel router. | -| `choiceId` | Oui | `string` | ID de choix d’authentification stable utilisé par les flux d’onboarding et de CLI. | -| `choiceLabel` | Non | `string` | Libellé destiné à l’utilisateur. S’il est omis, OpenClaw utilise `choiceId` comme valeur de repli. | -| `choiceHint` | Non | `string` | Court texte d’aide pour le sélecteur. | -| `assistantPriority` | Non | `number` | Les valeurs les plus basses sont triées plus tôt dans les sélecteurs interactifs pilotés par l’assistant. | -| `assistantVisibility` | Non | `"visible"` \| `"manual-only"` | Masque ce choix dans les sélecteurs de l’assistant tout en autorisant sa sélection manuelle en CLI. | -| `deprecatedChoiceIds` | Non | `string[]` | IDs de choix hérités qui doivent rediriger les utilisateurs vers ce choix de remplacement. | -| `groupId` | Non | `string` | ID de groupe facultatif pour regrouper des choix liés. | -| `groupLabel` | Non | `string` | Libellé destiné à l’utilisateur pour ce groupe. | -| `groupHint` | Non | `string` | Court texte d’aide pour le groupe. | -| `optionKey` | Non | `string` | Clé d’option interne pour les flux d’authentification simples à un seul flag. | -| `cliFlag` | Non | `string` | Nom du flag CLI, par exemple `--openrouter-api-key`. | -| `cliOption` | Non | `string` | Forme complète de l’option CLI, par exemple `--openrouter-api-key `. | -| `cliDescription` | Non | `string` | Description utilisée dans l’aide CLI. | +| Champ | Obligatoire | Type | Signification | +| --------------------- | ----------- | ----------------------------------------------- | ---------------------------------------------------------------------------------------------------------- | +| `provider` | Oui | `string` | ID du fournisseur auquel ce choix appartient. | +| `method` | Oui | `string` | ID de la méthode d’authentification vers laquelle répartir. | +| `choiceId` | Oui | `string` | ID stable de choix d’authentification utilisé par les flux d’onboarding et CLI. | +| `choiceLabel` | Non | `string` | Libellé destiné à l’utilisateur. S’il est omis, OpenClaw utilise `choiceId` comme repli. | +| `choiceHint` | Non | `string` | Court texte d’aide pour le sélecteur. | +| `assistantPriority` | Non | `number` | Les valeurs plus faibles sont triées plus tôt dans les sélecteurs interactifs pilotés par l’assistant. | +| `assistantVisibility` | Non | `"visible"` \| `"manual-only"` | Masque ce choix dans les sélecteurs de l’assistant tout en autorisant la sélection manuelle via la CLI. | +| `deprecatedChoiceIds` | Non | `string[]` | IDs hérités de choix qui doivent rediriger les utilisateurs vers ce choix de remplacement. | +| `groupId` | Non | `string` | ID de groupe facultatif pour regrouper des choix liés. | +| `groupLabel` | Non | `string` | Libellé destiné à l’utilisateur pour ce groupe. | +| `groupHint` | Non | `string` | Court texte d’aide pour le groupe. | +| `optionKey` | Non | `string` | Clé d’option interne pour les flux d’authentification simples à un seul flag. | +| `cliFlag` | Non | `string` | Nom du flag CLI, tel que `--openrouter-api-key`. | +| `cliOption` | Non | `string` | Forme complète de l’option CLI, telle que `--openrouter-api-key `. | +| `cliDescription` | Non | `string` | Description utilisée dans l’aide CLI. | | `onboardingScopes` | Non | `Array<"text-inference" \| "image-generation">` | Sur quelles surfaces d’onboarding ce choix doit apparaître. S’il est omis, la valeur par défaut est `["text-inference"]`. | -## Référence `commandAliases` +## Référence de `commandAliases` -Utilisez `commandAliases` lorsqu’un Plugin possède un nom de commande runtime que les utilisateurs peuvent -mettre par erreur dans `plugins.allow` ou essayer d’exécuter comme commande CLI racine. OpenClaw -utilise ces métadonnées pour les diagnostics sans importer le code runtime du Plugin. +Utilisez `commandAliases` lorsqu’un Plugin possède un nom de commande d’exécution que les utilisateurs peuvent +mettre par erreur dans `plugins.allow` ou essayer d’exécuter comme une commande CLI racine. OpenClaw +utilise ces métadonnées pour les diagnostics sans importer le code d’exécution du Plugin. ```json { @@ -211,22 +211,44 @@ utilise ces métadonnées pour les diagnostics sans importer le code runtime du } ``` -| Champ | Obligatoire | Type | Ce que cela signifie | -| ------------ | ----------- | ----------------- | ----------------------------------------------------------------------- | -| `name` | Oui | `string` | Nom de commande appartenant à ce Plugin. | +| Champ | Obligatoire | Type | Signification | +| ------------ | ----------- | ----------------- | --------------------------------------------------------------------------------- | +| `name` | Oui | `string` | Nom de commande qui appartient à ce Plugin. | | `kind` | Non | `"runtime-slash"` | Marque l’alias comme une commande slash de chat plutôt qu’une commande CLI racine. | -| `cliCommand` | Non | `string` | Commande CLI racine associée à suggérer pour les opérations CLI, si elle existe. | +| `cliCommand` | Non | `string` | Commande CLI racine associée à suggérer pour les opérations CLI, si elle existe. | -## Référence `activation` +## Référence de `activation` Utilisez `activation` lorsque le Plugin peut déclarer à faible coût quels événements du plan de contrôle -doivent l’activer ultérieurement. +doivent l’activer plus tard. -Ce bloc contient uniquement des métadonnées. Il n’enregistre pas le comportement runtime, et il -ne remplace pas `register(...)`, `setupEntry` ni les autres points d’entrée runtime/Plugin. -Les consommateurs actuels l’utilisent comme indication de restriction avant un chargement plus large des Plugins, donc -l’absence de métadonnées d’activation ne coûte généralement que des performances ; elle ne doit pas -modifier le comportement tant que les replis hérités de propriété du manifeste existent encore. +## Référence de `qaRunners` + +Utilisez `qaRunners` lorsqu’un Plugin contribue à un ou plusieurs exécuteurs de transport sous la racine partagée +`openclaw qa`. Gardez ces métadonnées simples et statiques ; l’environnement d’exécution du Plugin reste responsable de l’enregistrement CLI réel via une surface légère +`runtime-api.ts` qui exporte `qaRunnerCliRegistrations`. + +```json +{ + "qaRunners": [ + { + "commandName": "matrix", + "description": "Exécuter la voie QA Matrix en direct, adossée à Docker, sur un homeserver jetable" + } + ] +} +``` + +| Champ | Obligatoire | Type | Signification | +| ------------- | ----------- | -------- | ------------------------------------------------------------------- | +| `commandName` | Oui | `string` | Sous-commande montée sous `openclaw qa`, par exemple `matrix`. | +| `description` | Non | `string` | Texte d’aide de repli utilisé lorsque l’hôte partagé a besoin d’une commande factice. | + +Ce bloc contient uniquement des métadonnées. Il n’enregistre pas de comportement d’exécution et +ne remplace pas `register(...)`, `setupEntry` ni d’autres points d’entrée d’exécution/de Plugin. +Les consommateurs actuels l’utilisent comme un indice de filtrage avant un chargement plus large du Plugin, donc +l’absence de métadonnées d’activation n’a généralement qu’un coût de performance ; elle ne devrait pas +modifier la correction tant que les replis hérités de propriété du manifeste existent encore. ```json { @@ -240,27 +262,28 @@ modifier le comportement tant que les replis hérités de propriété du manifes } ``` -| Champ | Obligatoire | Type | Ce que cela signifie | -| ---------------- | ----------- | ---------------------------------------------------- | ------------------------------------------------------------------- | +| Champ | Obligatoire | Type | Signification | +| ---------------- | ----------- | ---------------------------------------------------- | ----------------------------------------------------------------- | | `onProviders` | Non | `string[]` | IDs de fournisseurs qui doivent activer ce Plugin lorsqu’ils sont demandés. | -| `onCommands` | Non | `string[]` | IDs de commandes qui doivent activer ce Plugin. | -| `onChannels` | Non | `string[]` | IDs de canaux qui doivent activer ce Plugin. | -| `onRoutes` | Non | `string[]` | Types de routes qui doivent activer ce Plugin. | -| `onCapabilities` | Non | `Array<"provider" \| "channel" \| "tool" \| "hook">` | Indications générales de capacité utilisées par la planification d’activation du plan de contrôle. | +| `onCommands` | Non | `string[]` | IDs de commandes qui doivent activer ce Plugin. | +| `onChannels` | Non | `string[]` | IDs de canaux qui doivent activer ce Plugin. | +| `onRoutes` | Non | `string[]` | Types de routes qui doivent activer ce Plugin. | +| `onCapabilities` | Non | `Array<"provider" \| "channel" \| "tool" \| "hook">` | Indications générales de capacités utilisées par la planification d’activation du plan de contrôle. | -Consommateurs actifs actuels : +Consommateurs actifs actuels : -- la planification CLI déclenchée par commande revient au comportement hérité +- la planification CLI déclenchée par commande utilise comme repli `commandAliases[].cliCommand` ou `commandAliases[].name` -- la planification de configuration/canal déclenchée par canal revient à la propriété héritée `channels[]` - lorsque les métadonnées explicites d’activation de canal sont absentes -- la planification de configuration/runtime déclenchée par fournisseur revient à la propriété héritée - `providers[]` et au `cliBackends[]` de premier niveau lorsque les métadonnées explicites d’activation de fournisseur sont absentes +- la planification de configuration/de canal déclenchée par canal utilise comme repli la propriété héritée `channels[]` + lorsqu’il manque des métadonnées explicites d’activation de canal +- la planification de configuration/d’exécution déclenchée par fournisseur utilise comme repli la propriété héritée + `providers[]` et la propriété de niveau supérieur `cliBackends[]` lorsque des métadonnées explicites d’activation + de fournisseur sont absentes -## Référence `setup` +## Référence de `setup` -Utilisez `setup` lorsque les surfaces de configuration et d’onboarding ont besoin de métadonnées peu coûteuses, détenues par le Plugin, -avant le chargement du runtime. +Utilisez `setup` lorsque les surfaces de configuration et d’onboarding ont besoin de métadonnées de Plugin, simples et détenues par le Plugin, +avant le chargement de l’environnement d’exécution. ```json { @@ -279,47 +302,48 @@ avant le chargement du runtime. } ``` -Le `cliBackends` de premier niveau reste valide et continue de décrire les -backends d’inférence CLI. `setup.cliBackends` est la surface de descripteur spécifique à la configuration pour -les flux du plan de contrôle/configuration qui doivent rester limités aux métadonnées. +Le `cliBackends` de niveau supérieur reste valide et continue de décrire les +backends d’inférence CLI. `setup.cliBackends` est la surface de descripteur spécifique à la configuration pour les +flux de configuration/plan de contrôle qui doivent rester uniquement basés sur des métadonnées. -Lorsqu’ils sont présents, `setup.providers` et `setup.cliBackends` sont la surface -de recherche privilégiée, d’abord fondée sur le descripteur, pour la découverte de configuration. Si le descripteur ne fait -que restreindre le Plugin candidat et que la configuration a encore besoin de hooks runtime plus riches au moment de la configuration, +Lorsqu’ils sont présents, `setup.providers` et `setup.cliBackends` constituent la +surface privilégiée, d’abord basée sur des descripteurs, pour la découverte de la configuration. Si le descripteur se contente uniquement +de restreindre le Plugin candidat et que la configuration a encore besoin de hooks d’exécution plus riches au moment de la configuration, définissez `requiresRuntime: true` et conservez `setup-api` comme chemin d’exécution de repli. -Étant donné que la recherche de configuration peut exécuter du code `setup-api` détenu par le Plugin, les valeurs -normalisées de `setup.providers[].id` et `setup.cliBackends[]` doivent rester uniques parmi -les Plugins découverts. Une propriété ambiguë échoue de manière conservatrice au lieu de choisir un gagnant selon l’ordre de découverte. +Comme la recherche de configuration peut exécuter du code `setup-api` détenu par le Plugin, +les valeurs normalisées `setup.providers[].id` et `setup.cliBackends[]` doivent rester uniques parmi tous les +Plugins découverts. Une propriété ambiguë échoue de manière fermée au lieu de choisir un +gagnant selon l’ordre de découverte. -### Référence `setup.providers` +### Référence de `setup.providers` -| Champ | Obligatoire | Type | Ce que cela signifie | -| ------------- | ----------- | ---------- | ----------------------------------------------------------------------------------------- | +| Champ | Obligatoire | Type | Signification | +| ------------- | ----------- | ---------- | ------------------------------------------------------------------------------------ | | `id` | Oui | `string` | ID du fournisseur exposé pendant la configuration ou l’onboarding. Gardez les IDs normalisés globalement uniques. | -| `authMethods` | Non | `string[]` | IDs des méthodes de configuration/authentification que ce fournisseur prend en charge sans charger le runtime complet. | -| `envVars` | Non | `string[]` | Variables d’environnement que les surfaces génériques de configuration/statut peuvent vérifier avant le chargement du runtime du Plugin. | +| `authMethods` | Non | `string[]` | IDs de méthodes de configuration/authentification que ce fournisseur prend en charge sans charger l’environnement d’exécution complet. | +| `envVars` | Non | `string[]` | Variables d’environnement que les surfaces génériques de configuration/statut peuvent vérifier avant le chargement de l’environnement d’exécution du Plugin. | -### Champs `setup` +### Champs de `setup` -| Champ | Obligatoire | Type | Ce que cela signifie | -| ------------------ | ----------- | ---------- | --------------------------------------------------------------------------------------------------------- | -| `providers` | Non | `object[]` | Descripteurs de configuration de fournisseurs exposés pendant la configuration et l’onboarding. | -| `cliBackends` | Non | `string[]` | IDs de backends au moment de la configuration utilisés pour la recherche de configuration fondée d’abord sur le descripteur. Gardez les IDs normalisés globalement uniques. | -| `configMigrations` | Non | `string[]` | IDs de migrations de configuration détenus par la surface de configuration de ce Plugin. | -| `requiresRuntime` | Non | `boolean` | Indique si la configuration nécessite encore l’exécution de `setup-api` après la recherche par descripteur. | +| Champ | Obligatoire | Type | Signification | +| ------------------ | ----------- | ---------- | --------------------------------------------------------------------------------------------------- | +| `providers` | Non | `object[]` | Descripteurs de configuration du fournisseur exposés pendant la configuration et l’onboarding. | +| `cliBackends` | Non | `string[]` | IDs de backend au moment de la configuration utilisés pour une recherche de configuration d’abord basée sur des descripteurs. Gardez les IDs normalisés globalement uniques. | +| `configMigrations` | Non | `string[]` | IDs de migration de configuration détenus par la surface de configuration de ce Plugin. | +| `requiresRuntime` | Non | `boolean` | Indique si la configuration a encore besoin de l’exécution de `setup-api` après la recherche par descripteur. | -## Référence `uiHints` +## Référence de `uiHints` -`uiHints` est une map reliant les noms de champs de configuration à de petites indications d’affichage. +`uiHints` est une correspondance entre les noms de champs de configuration et de petites indications de rendu. ```json { "uiHints": { "apiKey": { - "label": "API key", - "help": "Used for OpenRouter requests", + "label": "Clé API", + "help": "Utilisée pour les requêtes OpenRouter", "placeholder": "sk-or-v1-...", "sensitive": true } @@ -327,21 +351,21 @@ les Plugins découverts. Une propriété ambiguë échoue de manière conservatr } ``` -Chaque indication de champ peut inclure : +Chaque indication de champ peut inclure : -| Champ | Type | Ce que cela signifie | -| ------------- | ---------- | ----------------------------------------- | +| Champ | Type | Signification | +| ------------- | ---------- | --------------------------------------- | | `label` | `string` | Libellé du champ destiné à l’utilisateur. | -| `help` | `string` | Court texte d’aide. | -| `tags` | `string[]` | Tags d’interface facultatifs. | -| `advanced` | `boolean` | Marque le champ comme avancé. | +| `help` | `string` | Court texte d’aide. | +| `tags` | `string[]` | Tags d’interface facultatifs. | +| `advanced` | `boolean` | Marque le champ comme avancé. | | `sensitive` | `boolean` | Marque le champ comme secret ou sensible. | -| `placeholder` | `string` | Texte d’exemple pour les champs de formulaire. | +| `placeholder` | `string` | Texte d’espace réservé pour les champs de formulaire. | -## Référence `contracts` +## Référence de `contracts` Utilisez `contracts` uniquement pour les métadonnées statiques de propriété de capacités qu’OpenClaw peut -lire sans importer le runtime du Plugin. +lire sans importer l’environnement d’exécution du Plugin. ```json { @@ -359,24 +383,24 @@ lire sans importer le runtime du Plugin. } ``` -Chaque liste est facultative : +Chaque liste est facultative : -| Champ | Type | Ce que cela signifie | -| -------------------------------- | ---------- | ------------------------------------------------------------ | -| `speechProviders` | `string[]` | IDs de fournisseurs de parole détenus par ce Plugin. | -| `realtimeTranscriptionProviders` | `string[]` | IDs de fournisseurs de transcription temps réel détenus par ce Plugin. | -| `realtimeVoiceProviders` | `string[]` | IDs de fournisseurs de voix temps réel détenus par ce Plugin. | +| Champ | Type | Signification | +| -------------------------------- | ---------- | --------------------------------------------------------------- | +| `speechProviders` | `string[]` | IDs de fournisseurs de parole détenus par ce Plugin. | +| `realtimeTranscriptionProviders` | `string[]` | IDs de fournisseurs de transcription en temps réel détenus par ce Plugin. | +| `realtimeVoiceProviders` | `string[]` | IDs de fournisseurs de voix en temps réel détenus par ce Plugin. | | `mediaUnderstandingProviders` | `string[]` | IDs de fournisseurs de compréhension des médias détenus par ce Plugin. | | `imageGenerationProviders` | `string[]` | IDs de fournisseurs de génération d’images détenus par ce Plugin. | -| `videoGenerationProviders` | `string[]` | IDs de fournisseurs de génération vidéo détenus par ce Plugin. | -| `webFetchProviders` | `string[]` | IDs de fournisseurs de récupération web détenus par ce Plugin. | -| `webSearchProviders` | `string[]` | IDs de fournisseurs de recherche web détenus par ce Plugin. | +| `videoGenerationProviders` | `string[]` | IDs de fournisseurs de génération de vidéo détenus par ce Plugin. | +| `webFetchProviders` | `string[]` | IDs de fournisseurs de récupération web détenus par ce Plugin. | +| `webSearchProviders` | `string[]` | IDs de fournisseurs de recherche web détenus par ce Plugin. | | `tools` | `string[]` | Noms d’outils d’agent détenus par ce Plugin pour les vérifications de contrat intégrées. | -## Référence `channelConfigs` +## Référence de `channelConfigs` -Utilisez `channelConfigs` lorsqu’un Plugin de canal a besoin de métadonnées de configuration peu coûteuses avant -le chargement du runtime. +Utilisez `channelConfigs` lorsqu’un Plugin de canal a besoin de métadonnées de configuration simples avant +le chargement de l’environnement d’exécution. ```json { @@ -391,7 +415,7 @@ le chargement du runtime. }, "uiHints": { "homeserverUrl": { - "label": "Homeserver URL", + "label": "URL du homeserver", "placeholder": "https://matrix.example.com" } }, @@ -403,20 +427,20 @@ le chargement du runtime. } ``` -Chaque entrée de canal peut inclure : +Chaque entrée de canal peut inclure : -| Champ | Type | Ce que cela signifie | -| ------------- | ------------------------ | ------------------------------------------------------------------------------------- | -| `schema` | `object` | Schéma JSON pour `channels.`. Obligatoire pour chaque entrée déclarée de configuration de canal. | -| `uiHints` | `Record` | Libellés/placeholders/indications de sensibilité d’interface facultatifs pour cette section de configuration de canal. | -| `label` | `string` | Libellé du canal fusionné dans les surfaces de sélection et d’inspection lorsque les métadonnées runtime ne sont pas prêtes. | -| `description` | `string` | Courte description du canal pour les surfaces d’inspection et de catalogue. | -| `preferOver` | `string[]` | IDs de Plugins hérités ou de priorité inférieure que ce canal doit devancer dans les surfaces de sélection. | +| Champ | Type | Signification | +| ------------- | ------------------------ | ------------------------------------------------------------------------------------------ | +| `schema` | `object` | Schéma JSON pour `channels.`. Obligatoire pour chaque entrée de configuration de canal déclarée. | +| `uiHints` | `Record` | Libellés d’interface, espaces réservés et indications de sensibilité facultatifs pour cette section de configuration du canal. | +| `label` | `string` | Libellé du canal fusionné dans les surfaces de sélection et d’inspection lorsque les métadonnées d’exécution ne sont pas prêtes. | +| `description` | `string` | Courte description du canal pour les surfaces d’inspection et de catalogue. | +| `preferOver` | `string[]` | IDs de Plugin hérités ou de priorité inférieure que ce canal doit surpasser dans les surfaces de sélection. | -## Référence `modelSupport` +## Référence de `modelSupport` -Utilisez `modelSupport` lorsqu’OpenClaw doit déduire votre Plugin fournisseur à partir de -raccourcis d’ID de modèles comme `gpt-5.4` ou `claude-sonnet-4.6` avant le chargement du runtime du Plugin. +Utilisez `modelSupport` lorsqu’OpenClaw doit déduire votre Plugin fournisseur à partir +d’IDs abrégés de modèle comme `gpt-5.4` ou `claude-sonnet-4.6` avant le chargement de l’environnement d’exécution du Plugin. ```json { @@ -427,76 +451,75 @@ raccourcis d’ID de modèles comme `gpt-5.4` ou `claude-sonnet-4.6` avant le ch } ``` -OpenClaw applique l’ordre de priorité suivant : +OpenClaw applique cette priorité : - les références explicites `provider/model` utilisent les métadonnées de manifeste `providers` du propriétaire -- `modelPatterns` a priorité sur `modelPrefixes` +- `modelPatterns` l’emporte sur `modelPrefixes` - si un Plugin non intégré et un Plugin intégré correspondent tous deux, le Plugin non intégré l’emporte -- toute ambiguïté restante est ignorée jusqu’à ce que l’utilisateur ou la configuration spécifie un fournisseur +- les ambiguïtés restantes sont ignorées jusqu’à ce que l’utilisateur ou la configuration spécifie un fournisseur -Champs : +Champs : -| Champ | Type | Ce que cela signifie | -| --------------- | ---------- | ------------------------------------------------------------------------- | -| `modelPrefixes` | `string[]` | Préfixes comparés avec `startsWith` aux IDs abrégés de modèles. | -| `modelPatterns` | `string[]` | Sources regex comparées aux IDs abrégés de modèles après suppression du suffixe de profil. | +| Champ | Type | Signification | +| --------------- | ---------- | -------------------------------------------------------------------------------- | +| `modelPrefixes` | `string[]` | Préfixes comparés avec `startsWith` aux IDs abrégés de modèle. | +| `modelPatterns` | `string[]` | Sources regex comparées aux IDs abrégés de modèle après suppression du suffixe de profil. | -Les clés de capacité héritées de premier niveau sont obsolètes. Utilisez `openclaw doctor --fix` pour +Les clés de capacités héritées au niveau supérieur sont obsolètes. Utilisez `openclaw doctor --fix` pour déplacer `speechProviders`, `realtimeTranscriptionProviders`, `realtimeVoiceProviders`, `mediaUnderstandingProviders`, `imageGenerationProviders`, `videoGenerationProviders`, -`webFetchProviders` et `webSearchProviders` sous `contracts` ; le -chargement normal du manifeste ne traite plus ces champs de premier niveau comme -une propriété de capacité. +`webFetchProviders` et `webSearchProviders` sous `contracts` ; le chargement normal du +manifeste ne traite plus ces champs de niveau supérieur comme une +propriété de capacité. -## Manifeste versus `package.json` +## Manifeste versus package.json -Les deux fichiers remplissent des rôles différents : +Les deux fichiers remplissent des rôles différents : -| Fichier | À utiliser pour | -| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------- | -| `openclaw.plugin.json` | Découverte, validation de configuration, métadonnées de choix d’authentification et indications d’interface qui doivent exister avant l’exécution du code du Plugin | -| `package.json` | Métadonnées npm, installation des dépendances et bloc `openclaw` utilisé pour les points d’entrée, le filtrage d’installation, la configuration ou les métadonnées de catalogue | +| Fichier | Utilisation | +| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------ | +| `openclaw.plugin.json` | Découverte, validation de la configuration, métadonnées de choix d’authentification et indications d’interface qui doivent exister avant l’exécution du code du Plugin | +| `package.json` | Métadonnées npm, installation des dépendances et bloc `openclaw` utilisé pour les points d’entrée, le contrôle d’installation, la configuration ou les métadonnées de catalogue | -Si vous ne savez pas où placer une métadonnée, utilisez cette règle : +Si vous ne savez pas où placer une métadonnée, utilisez cette règle : - si OpenClaw doit la connaître avant de charger le code du Plugin, placez-la dans `openclaw.plugin.json` -- si elle concerne le packaging, les fichiers d’entrée ou le comportement d’installation npm, placez-la dans `package.json` +- si elle concerne le packaging, les fichiers de point d’entrée ou le comportement d’installation npm, placez-la dans `package.json` -### Champs `package.json` qui affectent la découverte +### Champs de package.json qui affectent la découverte -Certaines métadonnées de Plugin avant runtime vivent volontairement dans `package.json` sous le -bloc `openclaw` plutôt que dans `openclaw.plugin.json`. +Certaines métadonnées de Plugin avant exécution vivent intentionnellement dans `package.json` sous le +bloc `openclaw` au lieu de `openclaw.plugin.json`. -Exemples importants : +Exemples importants : -| Champ | Ce que cela signifie | -| ----------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- | -| `openclaw.extensions` | Déclare les points d’entrée de Plugins natifs. | -| `openclaw.setupEntry` | Point d’entrée léger réservé à la configuration, utilisé pendant l’onboarding et le démarrage différé des canaux. | -| `openclaw.channel` | Métadonnées légères de catalogue de canal comme les libellés, chemins de documentation, alias et texte de sélection. | -| `openclaw.channel.configuredState` | Métadonnées légères du vérificateur d’état configuré qui peuvent répondre à « une configuration uniquement via env existe-t-elle déjà ? » sans charger le runtime complet du canal. | -| `openclaw.channel.persistedAuthState` | Métadonnées légères du vérificateur d’authentification persistée qui peuvent répondre à « y a-t-il déjà quelque chose de connecté ? » sans charger le runtime complet du canal. | -| `openclaw.install.npmSpec` / `openclaw.install.localPath` | Indications d’installation/mise à jour pour les Plugins intégrés et publiés externement. | -| `openclaw.install.defaultChoice` | Chemin d’installation préféré lorsque plusieurs sources d’installation sont disponibles. | -| `openclaw.install.minHostVersion` | Version minimale prise en charge de l’hôte OpenClaw, avec un plancher semver comme `>=2026.3.22`. | -| `openclaw.install.allowInvalidConfigRecovery` | Autorise un chemin de récupération de réinstallation étroit pour un Plugin intégré lorsque la configuration est invalide. | -| `openclaw.startup.deferConfiguredChannelFullLoadUntilAfterListen` | Permet aux surfaces de canal réservées à la configuration de se charger avant le Plugin de canal complet au démarrage. | +| Champ | Signification | +| ----------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | +| `openclaw.extensions` | Déclare les points d’entrée de Plugin natifs. | +| `openclaw.setupEntry` | Point d’entrée léger, réservé à la configuration, utilisé pendant l’onboarding et le démarrage différé des canaux. | +| `openclaw.channel` | Métadonnées simples de catalogue de canal, comme les libellés, chemins de documentation, alias et texte de sélection. | +| `openclaw.channel.configuredState` | Métadonnées légères du vérificateur d’état configuré pouvant répondre à « une configuration uniquement par variables d’environnement existe-t-elle déjà ? » sans charger l’environnement d’exécution complet du canal. | +| `openclaw.channel.persistedAuthState` | Métadonnées légères du vérificateur d’authentification persistée pouvant répondre à « quelque chose est-il déjà connecté ? » sans charger l’environnement d’exécution complet du canal. | +| `openclaw.install.npmSpec` / `openclaw.install.localPath` | Indications d’installation/mise à jour pour les Plugins intégrés et publiés en externe. | +| `openclaw.install.defaultChoice` | Chemin d’installation préféré lorsque plusieurs sources d’installation sont disponibles. | +| `openclaw.install.minHostVersion` | Version minimale prise en charge de l’hôte OpenClaw, en utilisant un plancher semver comme `>=2026.3.22`. | +| `openclaw.install.allowInvalidConfigRecovery` | Autorise un chemin de récupération étroit pour la réinstallation d’un Plugin intégré lorsque la configuration est invalide. | +| `openclaw.startup.deferConfiguredChannelFullLoadUntilAfterListen` | Permet aux surfaces de canal réservées à la configuration de se charger avant le Plugin de canal complet au démarrage. | -`openclaw.install.minHostVersion` est appliqué pendant l’installation et le -chargement du registre de manifestes. Les valeurs invalides sont rejetées ; les valeurs valides mais plus récentes ignorent le +`openclaw.install.minHostVersion` est appliqué pendant l’installation et le chargement du registre de manifestes. Les valeurs invalides sont rejetées ; les valeurs valides mais plus récentes ignorent le Plugin sur les hôtes plus anciens. -`openclaw.install.allowInvalidConfigRecovery` est volontairement limité. Il -ne rend pas installables des configurations arbitrairement cassées. Aujourd’hui, il permet seulement aux flux d’installation -de récupérer à partir de certaines pannes obsolètes de mise à niveau d’un Plugin intégré, comme un +`openclaw.install.allowInvalidConfigRecovery` est intentionnellement étroit. Il +ne rend pas arbitrairement installables des configurations cassées. Aujourd’hui, il permet seulement aux flux d’installation +de récupérer à partir d’échecs spécifiques de mise à niveau d’un Plugin intégré devenu obsolète, comme un chemin de Plugin intégré manquant ou une entrée `channels.` obsolète pour ce même -Plugin intégré. Les erreurs de configuration non liées bloquent toujours l’installation et redirigent les opérateurs +Plugin intégré. Les erreurs de configuration non liées bloquent toujours l’installation et envoient les opérateurs vers `openclaw doctor --fix`. -`openclaw.channel.persistedAuthState` est une métadonnée de package pour un minuscule -module de vérification : +`openclaw.channel.persistedAuthState` est une métadonnée de package pour un petit +module de vérification : ```json { @@ -512,13 +535,13 @@ module de vérification : } ``` -Utilisez-le lorsque les flux de configuration, de doctor ou d’état configuré ont besoin d’une -vérification d’authentification oui/non peu coûteuse avant le chargement du Plugin de canal complet. L’export cible doit être une petite -fonction qui lit uniquement l’état persisté ; ne le faites pas transiter par le barrel runtime complet du +Utilisez-le lorsque les flux de configuration, doctor ou d’état configuré ont besoin d’une +vérification simple oui/non de l’authentification avant le chargement du Plugin de canal complet. L’export ciblé doit être une petite +fonction qui lit uniquement l’état persisté ; ne la faites pas transiter par le barrel complet de l’environnement d’exécution du canal. -`openclaw.channel.configuredState` suit la même structure pour des vérifications peu coûteuses -de l’état configuré uniquement via env : +`openclaw.channel.configuredState` suit la même forme pour des vérifications simples d’état +configuré uniquement basées sur l’environnement : ```json { @@ -534,9 +557,10 @@ de l’état configuré uniquement via env : } ``` -Utilisez-le lorsqu’un canal peut répondre à l’état configuré à partir de l’env ou d’autres petites -entrées hors runtime. Si la vérification nécessite la résolution complète de la configuration ou le véritable -runtime du canal, conservez plutôt cette logique dans le hook `config.hasConfiguredState` du Plugin. +Utilisez-le lorsqu’un canal peut répondre à l’état configuré à partir de variables d’environnement ou d’autres petites +entrées hors environnement d’exécution. Si la vérification nécessite une résolution complète de la configuration ou le véritable +environnement d’exécution du canal, conservez cette logique dans le hook `config.hasConfiguredState` +du Plugin à la place. ## Exigences du schéma JSON @@ -549,49 +573,49 @@ runtime du canal, conservez plutôt cette logique dans le hook `config.hasConfig - Les clés inconnues dans `channels.*` sont des **erreurs**, sauf si l’ID de canal est déclaré par un manifeste de Plugin. - `plugins.entries.`, `plugins.allow`, `plugins.deny` et `plugins.slots.*` - doivent référencer des IDs de Plugin **détectables**. Les IDs inconnus sont des **erreurs**. + doivent référencer des IDs de Plugin **découvrables**. Les IDs inconnus sont des **erreurs**. - Si un Plugin est installé mais possède un manifeste ou un schéma cassé ou manquant, la validation échoue et Doctor signale l’erreur du Plugin. - Si une configuration de Plugin existe mais que le Plugin est **désactivé**, la configuration est conservée et - un **avertissement** apparaît dans Doctor et dans les journaux. + un **avertissement** est remonté dans Doctor + les journaux. -Voir [Configuration reference](/fr/gateway/configuration) pour le schéma complet `plugins.*`. +Consultez [Référence de configuration](/fr/gateway/configuration) pour le schéma complet de `plugins.*`. ## Remarques -- Le manifeste est **obligatoire pour les Plugins natifs OpenClaw**, y compris pour les chargements depuis le système de fichiers local. -- Le runtime charge toujours le module du Plugin séparément ; le manifeste sert uniquement à la +- Le manifeste est **obligatoire pour les Plugins OpenClaw natifs**, y compris les chargements depuis le système de fichiers local. +- L’environnement d’exécution charge toujours le module du Plugin séparément ; le manifeste sert uniquement à la découverte + validation. - Les manifestes natifs sont analysés avec JSON5, donc les commentaires, les virgules finales et les - clés non entre guillemets sont acceptés tant que la valeur finale reste un objet. + clés non entre guillemets sont acceptés tant que la valeur finale reste bien un objet. - Seuls les champs de manifeste documentés sont lus par le chargeur de manifeste. Évitez d’ajouter - ici des clés personnalisées de premier niveau. -- `providerAuthEnvVars` est le chemin de métadonnées peu coûteux pour les sondes d’authentification, la - validation des marqueurs d’environnement et les surfaces similaires d’authentification fournisseur qui ne doivent pas démarrer le runtime du Plugin + ici des clés personnalisées au niveau supérieur. +- `providerAuthEnvVars` est le chemin de métadonnées simple pour les sondes d’authentification, la + validation des marqueurs de variables d’environnement et les surfaces similaires d’authentification de fournisseur + qui ne doivent pas démarrer l’environnement d’exécution du Plugin uniquement pour inspecter les noms de variables d’environnement. +- `providerAuthAliases` permet à des variantes de fournisseur de réutiliser les variables d’environnement d’authentification, + les profils d’authentification, l’authentification adossée à la configuration et le choix d’onboarding par clé API + d’un autre fournisseur sans coder en dur cette relation dans le cœur. +- `channelEnvVars` est le chemin de métadonnées simple pour le repli basé sur les variables d’environnement du shell, les invites de configuration + et les surfaces de canal similaires qui ne doivent pas démarrer l’environnement d’exécution du Plugin uniquement pour inspecter les noms de variables d’environnement. -- `providerAuthAliases` permet à des variantes de fournisseurs de réutiliser les variables d’environnement d’authentification - d’un autre fournisseur, ses profils d’authentification, son authentification adossée à la configuration et son choix - d’onboarding par clé d’API sans coder cette relation en dur dans le cœur. -- `channelEnvVars` est le chemin de métadonnées peu coûteux pour le repli via l’environnement shell, les invites de configuration - et les surfaces de canal similaires qui ne doivent pas démarrer le runtime du Plugin - uniquement pour inspecter les noms de variables d’environnement. -- `providerAuthChoices` est le chemin de métadonnées peu coûteux pour les sélecteurs de choix d’authentification, - la résolution de `--auth-choice`, le mapping du fournisseur préféré et l’enregistrement simple de flags CLI - d’onboarding avant le chargement du runtime du fournisseur. Pour les métadonnées d’assistant runtime - qui nécessitent le code du fournisseur, voir - [Provider runtime hooks](/fr/plugins/architecture#provider-runtime-hooks). -- Les types de Plugin exclusifs sont sélectionnés via `plugins.slots.*`. +- `providerAuthChoices` est le chemin de métadonnées simple pour les sélecteurs de choix d’authentification, + la résolution de `--auth-choice`, la correspondance avec le fournisseur préféré et l’enregistrement simple des flags CLI + d’onboarding avant le chargement de l’environnement d’exécution du fournisseur. Pour les métadonnées d’assistant d’exécution + qui nécessitent du code fournisseur, consultez + [Hooks d’exécution de fournisseur](/fr/plugins/architecture#provider-runtime-hooks). +- Les types exclusifs de Plugin sont sélectionnés via `plugins.slots.*`. - `kind: "memory"` est sélectionné par `plugins.slots.memory`. - `kind: "context-engine"` est sélectionné par `plugins.slots.contextEngine` - (par défaut : `legacy` intégré). + (par défaut : `legacy` intégré). - `channels`, `providers`, `cliBackends` et `skills` peuvent être omis lorsqu’un Plugin n’en a pas besoin. -- Si votre Plugin dépend de modules natifs, documentez les étapes de build et toute +- Si votre Plugin dépend de modules natifs, documentez les étapes de build ainsi que toute exigence de liste d’autorisation du gestionnaire de paquets (par exemple, pnpm `allow-build-scripts` - `pnpm rebuild `). -## Connexe +## Lié -- [Building Plugins](/fr/plugins/building-plugins) — prise en main des Plugins -- [Plugin Architecture](/fr/plugins/architecture) — architecture interne -- [SDK Overview](/fr/plugins/sdk-overview) — référence du SDK de Plugin +- [Créer des Plugins](/fr/plugins/building-plugins) — bien démarrer avec les Plugins +- [Architecture des Plugins](/fr/plugins/architecture) — architecture interne +- [Vue d’ensemble du SDK](/fr/plugins/sdk-overview) — référence du SDK de Plugin diff --git a/docs/fr/plugins/sdk-channel-plugins.md b/docs/fr/plugins/sdk-channel-plugins.md index 72453c246..4752e3e73 100644 --- a/docs/fr/plugins/sdk-channel-plugins.md +++ b/docs/fr/plugins/sdk-channel-plugins.md @@ -1,104 +1,110 @@ --- read_when: - - Vous créez un nouveau plugin de canal de messagerie - - Vous souhaitez connecter OpenClaw à une plateforme de messagerie - - Vous devez comprendre la surface d’adaptation `ChannelPlugin` + - Vous créez un nouveau Plugin de canal de messagerie. + - Vous souhaitez connecter OpenClaw à une plateforme de messagerie. + - Vous devez comprendre la surface d’adaptation de `ChannelPlugin` sidebarTitle: Channel Plugins -summary: Guide étape par étape pour créer un plugin de canal de messagerie pour OpenClaw -title: Créer des plugins de canal +summary: Guide étape par étape pour créer un Plugin de canal de messagerie pour OpenClaw +title: Créer des Plugins de canal x-i18n: - generated_at: "2026-04-11T02:46:17Z" + generated_at: "2026-04-15T06:56:34Z" model: gpt-5.4 provider: openai - source_hash: 8a026e924f9ae8a3ddd46287674443bcfccb0247be504261522b078e1f440aef + source_hash: a7f4c746fe3163a8880e14c433f4db4a1475535d91716a53fb879551d8d62f65 source_path: plugins/sdk-channel-plugins.md workflow: 15 --- -# Créer des plugins de canal +# Créer des Plugins de canal -Ce guide vous accompagne dans la création d’un plugin de canal qui connecte OpenClaw à une -plateforme de messagerie. À la fin, vous disposerez d’un canal fonctionnel avec sécurité des DM, -appairage, threading des réponses, et messagerie sortante. +Ce guide explique comment créer un Plugin de canal qui connecte OpenClaw à une +plateforme de messagerie. À la fin, vous disposerez d’un canal fonctionnel avec la sécurité des DM, +l’appairage, le fil des réponses et la messagerie sortante. - Si vous n’avez encore créé aucun plugin OpenClaw, lisez d’abord + Si vous n’avez encore créé aucun Plugin OpenClaw, lisez d’abord [Getting Started](/fr/plugins/building-plugins) pour la structure de package de base et la configuration du manifeste. -## Fonctionnement des plugins de canal +## Fonctionnement des Plugins de canal -Les plugins de canal n’ont pas besoin de leurs propres outils send/edit/react. OpenClaw conserve un -outil `message` partagé dans le core. Votre plugin possède : +Les Plugins de canal n’ont pas besoin de leurs propres outils d’envoi/modification/réaction. OpenClaw conserve un +outil `message` partagé dans le cœur. Votre Plugin gère : -- **Config** — résolution des comptes et assistant de configuration -- **Security** — politique DM et listes d’autorisation -- **Pairing** — flux d’approbation des DM -- **Session grammar** — manière dont les ids de conversation propres au fournisseur se mappent aux chats de base, aux ids de thread, et aux fallbacks parents -- **Outbound** — envoi de texte, médias, et sondages vers la plateforme -- **Threading** — manière dont les réponses sont threadées +- **Configuration** — résolution de compte et assistant de configuration +- **Sécurité** — politique DM et listes d’autorisation +- **Appairage** — flux d’approbation des DM +- **Grammaire de session** — comment les identifiants de conversation propres au fournisseur sont mappés vers les discussions de base, les identifiants de fil et les solutions de repli parent +- **Sortant** — envoi de texte, de médias et de sondages vers la plateforme +- **Fil des réponses** — comment les réponses sont organisées en fil -Le core possède l’outil message partagé, le câblage des prompts, la forme externe de la clé de session, -la gestion générique `:thread:`, et la répartition. +Le cœur gère l’outil de message partagé, le câblage des prompts, la forme externe de la clé de session, +la gestion générique `:thread:` et la distribution. -Si votre plateforme stocke une portée supplémentaire dans les ids de conversation, conservez cette analyse -dans le plugin avec `messaging.resolveSessionConversation(...)`. C’est le hook canonique pour mapper -`rawId` vers l’id de conversation de base, l’id de thread optionnel, `baseConversationId` explicite, -et tout `parentConversationCandidates`. -Lorsque vous renvoyez `parentConversationCandidates`, gardez-les ordonnés du parent -le plus étroit vers la conversation parente/la conversation de base la plus large. +Si votre canal ajoute des paramètres d’outil de message qui transportent des sources média, exposez ces +noms de paramètres via `describeMessageTool(...).mediaSourceParams`. Le cœur utilise +cette liste explicite pour la normalisation des chemins du sandbox et la politique +d’accès aux médias sortants, afin que les Plugins n’aient pas besoin de cas particuliers dans le cœur partagé pour des +paramètres spécifiques au fournisseur comme l’avatar, la pièce jointe ou l’image de couverture. +Préférez renvoyer une map indexée par action comme +`{ "set-profile": ["avatarUrl", "avatarPath"] }` afin que des actions sans lien n’héritent pas des arguments média d’une autre action. Un tableau plat fonctionne aussi pour des paramètres +volontairement partagés par chaque action exposée. -Les plugins intégrés qui ont besoin de la même analyse avant le démarrage du registre de canaux -peuvent aussi exposer un fichier `session-key-api.ts` de premier niveau avec un export -`resolveSessionConversation(...)` correspondant. Le core utilise cette surface sûre au bootstrap -uniquement lorsque le registre de plugins runtime n’est pas encore disponible. +Si votre plateforme stocke une portée supplémentaire dans les identifiants de conversation, conservez cette analyse +dans le Plugin avec `messaging.resolveSessionConversation(...)`. C’est le +hook canonique pour mapper `rawId` vers l’identifiant de conversation de base, l’identifiant de fil optionnel, +`baseConversationId` explicite, et tout `parentConversationCandidates`. +Lorsque vous renvoyez `parentConversationCandidates`, conservez leur ordre du +parent le plus spécifique vers la conversation parente la plus large/de base. -`messaging.resolveParentConversationCandidates(...)` reste disponible comme fallback de compatibilité -hérité lorsqu’un plugin n’a besoin que de fallbacks parents au-dessus de l’id générique/brut. -Si les deux hooks existent, le core utilise d’abord -`resolveSessionConversation(...).parentConversationCandidates` et ne retombe sur -`resolveParentConversationCandidates(...)` que lorsque le hook canonique +Les Plugins groupés qui ont besoin de la même analyse avant le démarrage du registre des canaux +peuvent aussi exposer un fichier de premier niveau `session-key-api.ts` avec un +export `resolveSessionConversation(...)` correspondant. Le cœur utilise cette surface sûre au démarrage +uniquement lorsque le registre de Plugin d’exécution n’est pas encore disponible. + +`messaging.resolveParentConversationCandidates(...)` reste disponible comme solution de repli de compatibilité héritée lorsqu’un Plugin n’a besoin de solutions de repli parent qu’au-dessus de l’identifiant générique/brut. Si les deux hooks existent, le cœur utilise +d’abord `resolveSessionConversation(...).parentConversationCandidates` et ne +revient à `resolveParentConversationCandidates(...)` que lorsque le hook canonique les omet. -## Approbations et capacités des canaux +## Approbations et capacités de canal -La plupart des plugins de canal n’ont pas besoin de code spécifique aux approbations. +La plupart des Plugins de canal n’ont pas besoin de code spécifique aux approbations. -- Le core possède `/approve` dans le même chat, les payloads partagés des boutons d’approbation, et la livraison de fallback générique. -- Préférez un seul objet `approvalCapability` sur le plugin de canal lorsque le canal a besoin d’un comportement spécifique aux approbations. -- `ChannelPlugin.approvals` est supprimé. Placez les faits d’approbation de livraison/natifs/rendu/authentification sur `approvalCapability`. -- `plugin.auth` sert uniquement à login/logout ; le core ne lit plus les hooks d’authentification d’approbation depuis cet objet. -- `approvalCapability.authorizeActorAction` et `approvalCapability.getActionAvailabilityState` sont la couture canonique pour l’authentification des approbations. -- Utilisez `approvalCapability.getActionAvailabilityState` pour la disponibilité de l’authentification des approbations dans le même chat. -- Si votre canal expose des approbations d’exécution natives, utilisez `approvalCapability.getExecInitiatingSurfaceState` pour l’état de la surface initiatrice/du client natif lorsqu’il diffère de l’authentification des approbations dans le même chat. Le core utilise ce hook spécifique à l’exécution pour distinguer `enabled` de `disabled`, décider si le canal initiateur prend en charge les approbations d’exécution natives, et inclure le canal dans les indications de fallback du client natif. `createApproverRestrictedNativeApprovalCapability(...)` remplit ce point pour le cas courant. -- Utilisez `outbound.shouldSuppressLocalPayloadPrompt` ou `outbound.beforeDeliverPayload` pour le comportement du cycle de vie des payloads spécifique au canal, par exemple masquer les prompts d’approbation locale en double ou envoyer des indicateurs de frappe avant la livraison. -- Utilisez `approvalCapability.delivery` uniquement pour le routage d’approbation natif ou la suppression de fallback. -- Utilisez `approvalCapability.nativeRuntime` pour les faits d’approbation native appartenant au canal. Gardez-le lazy sur les points d’entrée chauds du canal avec `createLazyChannelApprovalNativeRuntimeAdapter(...)`, qui peut importer votre module runtime à la demande tout en laissant le core assembler le cycle de vie des approbations. -- Utilisez `approvalCapability.render` uniquement lorsqu’un canal a réellement besoin de payloads d’approbation personnalisés au lieu du moteur de rendu partagé. -- Utilisez `approvalCapability.describeExecApprovalSetup` lorsque le canal veut que la réponse du chemin désactivé explique les paramètres de configuration exacts nécessaires pour activer les approbations d’exécution natives. Le hook reçoit `{ channel, channelLabel, accountId }` ; les canaux à compte nommé doivent afficher des chemins à portée de compte tels que `channels..accounts..execApprovals.*` au lieu de valeurs par défaut de niveau supérieur. -- Si un canal peut déduire des identités DM stables de type propriétaire à partir de la configuration existante, utilisez `createResolvedApproverActionAuthAdapter` depuis `openclaw/plugin-sdk/approval-runtime` pour restreindre `/approve` dans le même chat sans ajouter de logique core spécifique aux approbations. -- Si un canal a besoin d’une livraison d’approbation native, gardez le code du canal centré sur la normalisation de la cible ainsi que sur les faits de transport/présentation. Utilisez `createChannelExecApprovalProfile`, `createChannelNativeOriginTargetResolver`, `createChannelApproverDmTargetResolver`, et `createApproverRestrictedNativeApprovalCapability` depuis `openclaw/plugin-sdk/approval-runtime`. Placez les faits spécifiques au canal derrière `approvalCapability.nativeRuntime`, idéalement via `createChannelApprovalNativeRuntimeAdapter(...)` ou `createLazyChannelApprovalNativeRuntimeAdapter(...)`, afin que le core puisse assembler le gestionnaire et posséder le filtrage des requêtes, le routage, la déduplication, l’expiration, l’abonnement gateway, et les avis « routed elsewhere ». `nativeRuntime` est divisé en quelques coutures plus petites : +- Le cœur gère `/approve` dans la même discussion, les charges utiles de bouton d’approbation partagées et la livraison de repli générique. +- Préférez un seul objet `approvalCapability` sur le Plugin de canal lorsque le canal a besoin d’un comportement spécifique aux approbations. +- `ChannelPlugin.approvals` est supprimé. Placez les informations de livraison/rendu/authentification natives de l’approbation dans `approvalCapability`. +- `plugin.auth` concerne uniquement login/logout ; le cœur ne lit plus les hooks d’authentification des approbations depuis cet objet. +- `approvalCapability.authorizeActorAction` et `approvalCapability.getActionAvailabilityState` constituent la jonction canonique pour l’authentification des approbations. +- Utilisez `approvalCapability.getActionAvailabilityState` pour la disponibilité de l’authentification des approbations dans la même discussion. +- Si votre canal expose des approbations d’exécution natives, utilisez `approvalCapability.getExecInitiatingSurfaceState` pour l’état de la surface initiatrice/du client natif lorsqu’il diffère de l’authentification des approbations dans la même discussion. Le cœur utilise ce hook spécifique à exec pour distinguer `enabled` de `disabled`, déterminer si le canal initiateur prend en charge les approbations d’exécution natives, et inclure le canal dans les indications de repli du client natif. `createApproverRestrictedNativeApprovalCapability(...)` remplit ce rôle pour le cas courant. +- Utilisez `outbound.shouldSuppressLocalPayloadPrompt` ou `outbound.beforeDeliverPayload` pour le comportement spécifique au canal dans le cycle de vie des charges utiles, par exemple masquer les invites locales d’approbation en double ou envoyer des indicateurs de saisie avant la livraison. +- Utilisez `approvalCapability.delivery` uniquement pour le routage des approbations natives ou la suppression du repli. +- Utilisez `approvalCapability.nativeRuntime` pour les informations d’approbation native gérées par le canal. Gardez-le paresseux sur les points d’entrée chauds du canal avec `createLazyChannelApprovalNativeRuntimeAdapter(...)`, qui peut importer votre module d’exécution à la demande tout en permettant au cœur d’assembler le cycle de vie de l’approbation. +- Utilisez `approvalCapability.render` uniquement lorsqu’un canal a réellement besoin de charges utiles d’approbation personnalisées au lieu du moteur de rendu partagé. +- Utilisez `approvalCapability.describeExecApprovalSetup` lorsque le canal souhaite que la réponse du chemin désactivé explique les paramètres de configuration exacts nécessaires pour activer les approbations d’exécution natives. Le hook reçoit `{ channel, channelLabel, accountId }` ; les canaux à comptes nommés doivent afficher des chemins à portée de compte tels que `channels..accounts..execApprovals.*` au lieu de valeurs par défaut de premier niveau. +- Si un canal peut déduire des identités DM stables de type propriétaire à partir de la configuration existante, utilisez `createResolvedApproverActionAuthAdapter` depuis `openclaw/plugin-sdk/approval-runtime` pour restreindre `/approve` dans la même discussion sans ajouter de logique du cœur spécifique aux approbations. +- Si un canal a besoin d’une livraison d’approbation native, faites en sorte que le code du canal reste centré sur la normalisation de la cible ainsi que sur les informations de transport/de présentation. Utilisez `createChannelExecApprovalProfile`, `createChannelNativeOriginTargetResolver`, `createChannelApproverDmTargetResolver` et `createApproverRestrictedNativeApprovalCapability` depuis `openclaw/plugin-sdk/approval-runtime`. Placez les informations spécifiques au canal derrière `approvalCapability.nativeRuntime`, idéalement via `createChannelApprovalNativeRuntimeAdapter(...)` ou `createLazyChannelApprovalNativeRuntimeAdapter(...)`, afin que le cœur puisse assembler le gestionnaire et gérer lui-même le filtrage des requêtes, le routage, la déduplication, l’expiration, l’abonnement Gateway et les avis de routage externe. `nativeRuntime` est divisé en quelques jonctions plus petites : - `availability` — si le compte est configuré et si une requête doit être traitée -- `presentation` — mapper le modèle de vue d’approbation partagé en payloads natifs en attente/résolus/expirés ou en actions finales -- `transport` — préparer les cibles plus envoyer/mettre à jour/supprimer les messages d’approbation natifs -- `interactions` — hooks optionnels de bind/unbind/clear-action pour les boutons ou réactions natifs -- `observe` — hooks optionnels de diagnostic de livraison -- Si le canal a besoin d’objets possédés par le runtime comme un client, un jeton, une app Bolt, ou un récepteur webhook, enregistrez-les via `openclaw/plugin-sdk/channel-runtime-context`. Le registre générique de contexte runtime permet au core de bootstrapper des gestionnaires pilotés par capacité à partir de l’état de démarrage du canal sans ajouter de glue wrapper spécifique aux approbations. -- Recourez à `createChannelApprovalHandler` ou `createChannelNativeApprovalRuntime` de niveau inférieur uniquement lorsque la couture pilotée par capacité n’est pas encore assez expressive. -- Les canaux d’approbation native doivent router à la fois `accountId` et `approvalKind` via ces helpers. `accountId` conserve la portée de la politique d’approbation multi-comptes sur le bon compte bot, et `approvalKind` conserve le comportement d’approbation d’exécution vs plugin disponible pour le canal sans branches codées en dur dans le core. -- Le core possède désormais aussi les avis de reroutage d’approbation. Les plugins de canal ne doivent pas envoyer leurs propres messages de suivi « approval went to DMs / another channel » depuis `createChannelNativeApprovalRuntime` ; exposez plutôt un routage précis de l’origine + DM de l’approbateur via les helpers partagés de capacité d’approbation et laissez le core agréger les livraisons réelles avant de publier tout avis dans le chat initiateur. -- Préservez le type d’id d’approbation livré de bout en bout. Les clients natifs ne doivent pas - deviner ni réécrire le routage d’approbation d’exécution vs plugin à partir d’un état local au canal. +- `presentation` — mapper le modèle de vue d’approbation partagé vers des charges utiles natives en attente/résolues/expirées ou des actions finales +- `transport` — préparer les cibles puis envoyer/mettre à jour/supprimer des messages d’approbation natifs +- `interactions` — hooks facultatifs bind/unbind/clear-action pour les boutons ou réactions natifs +- `observe` — hooks facultatifs de diagnostic de livraison +- Si le canal a besoin d’objets gérés par l’exécution comme un client, un jeton, une app Bolt ou un récepteur Webhook, enregistrez-les via `openclaw/plugin-sdk/channel-runtime-context`. Le registre générique de contexte d’exécution permet au cœur d’amorcer des gestionnaires pilotés par les capacités à partir de l’état de démarrage du canal sans ajouter de colle d’encapsulation spécifique aux approbations. +- Utilisez les niveaux inférieurs `createChannelApprovalHandler` ou `createChannelNativeApprovalRuntime` uniquement lorsque la jonction pilotée par les capacités n’est pas encore suffisamment expressive. +- Les canaux d’approbation native doivent faire transiter à la fois `accountId` et `approvalKind` par ces helpers. `accountId` permet de garder la politique d’approbation multi-compte limitée au bon compte de bot, et `approvalKind` rend disponible au canal le comportement d’approbation exec vs Plugin sans branches codées en dur dans le cœur. +- Le cœur gère désormais aussi les avis de reroutage d’approbation. Les Plugins de canal ne doivent pas envoyer leurs propres messages de suivi « l’approbation a été envoyée vers les DM / un autre canal » depuis `createChannelNativeApprovalRuntime` ; exposez plutôt un routage précis de l’origine + des DM de l’approbateur via les helpers de capacité d’approbation partagés et laissez le cœur agréger les livraisons réelles avant de publier un éventuel avis dans la discussion initiatrice. +- Préservez le type d’identifiant d’approbation livré de bout en bout. Les clients natifs ne doivent pas + deviner ou réécrire le routage des approbations exec vs Plugin à partir d’un état local au canal. - Différents types d’approbation peuvent intentionnellement exposer différentes surfaces natives. - Exemples intégrés actuels : - - Slack conserve le routage d’approbation natif disponible pour les ids d’exécution et de plugin. - - Matrix conserve le même routage DM/canal natif et la même UX par réaction pour les approbations d’exécution - et de plugin, tout en permettant à l’authentification de différer selon le type d’approbation. -- `createApproverRestrictedNativeApprovalAdapter` existe toujours comme wrapper de compatibilité, mais le nouveau code doit préférer le builder de capacité et exposer `approvalCapability` sur le plugin. + Exemples groupés actuels : + - Slack maintient le routage d’approbation native disponible à la fois pour les identifiants exec et Plugin. + - Matrix conserve le même routage natif DM/canal et la même UX par réaction pour les approbations exec + et Plugin, tout en permettant à l’authentification de différer selon le type d’approbation. +- `createApproverRestrictedNativeApprovalAdapter` existe toujours comme encapsulation de compatibilité, mais le nouveau code doit préférer le constructeur de capacité et exposer `approvalCapability` sur le Plugin. -Pour les points d’entrée chauds du canal, préférez les sous-chemins runtime plus étroits lorsque vous n’avez besoin -que d’une partie de cette famille : +Pour les points d’entrée chauds du canal, préférez les sous-chemins d’exécution plus étroits lorsque vous n’avez besoin que d’une seule partie de cette famille : - `openclaw/plugin-sdk/approval-auth-runtime` - `openclaw/plugin-sdk/approval-client-runtime` @@ -116,92 +122,90 @@ De même, préférez `openclaw/plugin-sdk/setup-runtime`, `openclaw/plugin-sdk/reply-dispatch-runtime`, `openclaw/plugin-sdk/reply-reference`, et `openclaw/plugin-sdk/reply-chunking` lorsque vous n’avez pas besoin de la surface -ombrelle plus large. +parapluie plus large. Pour la configuration en particulier : -- `openclaw/plugin-sdk/setup-runtime` couvre les helpers de configuration sûrs au runtime : - adaptateurs de patch de configuration import-safe (`createPatchedAccountSetupAdapter`, +- `openclaw/plugin-sdk/setup-runtime` couvre les helpers de configuration sûrs à l’exécution : + adaptateurs de patch de configuration sûrs à l’import (`createPatchedAccountSetupAdapter`, `createEnvPatchedAccountSetupAdapter`, - `createSetupInputPresenceValidator`), sortie de note de lookup, - `promptResolvedAllowFrom`, `splitSetupEntries`, et les builders - délégués de setup-proxy -- `openclaw/plugin-sdk/setup-adapter-runtime` est la couture étroite d’adaptateur sensible à l’environnement + `createSetupInputPresenceValidator`), sortie de note de recherche, + `promptResolvedAllowFrom`, `splitSetupEntries`, et les constructeurs + de proxy de configuration déléguée +- `openclaw/plugin-sdk/setup-adapter-runtime` est la jonction d’adaptateur étroite sensible à l’environnement pour `createEnvPatchedAccountSetupAdapter` -- `openclaw/plugin-sdk/channel-setup` couvre les builders de configuration à installation optionnelle +- `openclaw/plugin-sdk/channel-setup` couvre les constructeurs de configuration avec installation facultative ainsi que quelques primitives sûres pour la configuration : `createOptionalChannelSetupSurface`, `createOptionalChannelSetupAdapter`, -Si votre canal prend en charge une configuration ou une authentification pilotée par l’environnement et que les flux génériques de démarrage/configuration -doivent connaître ces noms de variables d’environnement avant le chargement du runtime, déclarez-les dans le -manifeste du plugin avec `channelEnvVars`. Conservez les `envVars` runtime du canal ou les constantes locales -uniquement pour le texte destiné aux opérateurs. +Si votre canal prend en charge une configuration ou une authentification pilotée par l’environnement et que les flux génériques de démarrage/configuration doivent connaître ces noms de variables d’environnement avant le chargement de l’exécution, déclarez-les dans le manifeste du Plugin avec `channelEnvVars`. Conservez les `envVars` d’exécution du canal ou les constantes locales uniquement pour le texte destiné aux opérateurs. `createOptionalChannelSetupWizard`, `DEFAULT_ACCOUNT_ID`, `createTopLevelChannelDmPolicy`, `setSetupChannelEnabled`, et `splitSetupEntries` -- utilisez la couture plus large `openclaw/plugin-sdk/setup` uniquement lorsque vous avez aussi besoin des helpers partagés plus lourds de configuration/setup tels que +- utilisez la jonction plus large `openclaw/plugin-sdk/setup` uniquement lorsque vous avez également besoin des + helpers partagés plus lourds de configuration/config tels que `moveSingleAccountChannelSectionToDefaultAccount(...)` -Si votre canal veut seulement annoncer « installez d’abord ce plugin » dans les -surfaces de configuration, préférez `createOptionalChannelSetupSurface(...)`. L’adaptateur/l’assistant généré -échoue de manière fermée sur les écritures de configuration et la finalisation, et ils réutilisent -le même message d’installation requise dans la validation, la finalisation, et le texte du lien vers la documentation. +Si votre canal veut seulement annoncer « installez d’abord ce Plugin » dans les +surfaces de configuration, préférez `createOptionalChannelSetupSurface(...)`. L’adaptateur/assistant généré échoue de manière fermée sur les écritures de configuration et la finalisation, et il réutilise +le même message « installation requise » pour la validation, la finalisation et le texte +du lien vers la documentation. Pour les autres chemins chauds du canal, préférez les helpers étroits aux surfaces héritées plus larges : - `openclaw/plugin-sdk/account-core`, `openclaw/plugin-sdk/account-id`, `openclaw/plugin-sdk/account-resolution`, et - `openclaw/plugin-sdk/account-helpers` pour la configuration multi-comptes et - le fallback de compte par défaut + `openclaw/plugin-sdk/account-helpers` pour la configuration multi-compte et + le repli vers le compte par défaut - `openclaw/plugin-sdk/inbound-envelope` et - `openclaw/plugin-sdk/inbound-reply-dispatch` pour le câblage de route/enveloppe entrante - et d’enregistrement-et-répartition + `openclaw/plugin-sdk/inbound-reply-dispatch` pour le câblage de route/enveloppe entrante et + d’enregistrement-et-distribution - `openclaw/plugin-sdk/messaging-targets` pour l’analyse/la correspondance des cibles - `openclaw/plugin-sdk/outbound-media` et - `openclaw/plugin-sdk/outbound-runtime` pour le chargement des médias ainsi que les délégués - d’identité/envoi sortants -- `openclaw/plugin-sdk/thread-bindings-runtime` pour le cycle de vie des liaisons de thread + `openclaw/plugin-sdk/outbound-runtime` pour le chargement des médias ainsi que les + délégations d’identité/d’envoi sortants +- `openclaw/plugin-sdk/thread-bindings-runtime` pour le cycle de vie des liaisons de fil et l’enregistrement des adaptateurs -- `openclaw/plugin-sdk/agent-media-payload` uniquement lorsqu’une disposition héritée des champs - de payload agent/média est encore requise +- `openclaw/plugin-sdk/agent-media-payload` uniquement lorsqu’une disposition de champ de charge utile agent/média héritée + est encore requise - `openclaw/plugin-sdk/telegram-command-config` pour la normalisation des commandes personnalisées Telegram, - la validation des doublons/conflits, et un contrat de configuration de commandes - stable en fallback + la validation des doublons/conflits et un contrat de configuration de commandes + stable en repli -Les canaux d’authentification seule peuvent généralement s’arrêter au chemin par défaut : le core gère les approbations et le plugin expose simplement des capacités outbound/auth. Les canaux d’approbation native comme Matrix, Slack, Telegram, et les transports de chat personnalisés doivent utiliser les helpers natifs partagés au lieu de développer leur propre cycle de vie d’approbation. +Les canaux uniquement basés sur l’authentification peuvent généralement s’arrêter au chemin par défaut : le cœur gère les approbations et le Plugin expose simplement les capacités sortantes/d’authentification. Les canaux d’approbation native comme Matrix, Slack, Telegram et les transports de chat personnalisés doivent utiliser les helpers natifs partagés au lieu d’implémenter leur propre cycle de vie d’approbation. -## Politique de mention entrante +## Politique des mentions entrantes Conservez la gestion des mentions entrantes séparée en deux couches : -- collecte des preuves appartenant au plugin -- évaluation partagée de la politique +- collecte d’éléments de preuve gérée par le Plugin +- évaluation de politique partagée Utilisez `openclaw/plugin-sdk/channel-inbound` pour la couche partagée. -Bon cas d’usage pour la logique locale au plugin : +Convient bien à la logique locale au Plugin : - détection des réponses au bot - détection des citations du bot -- vérifications de participation au thread +- vérifications de participation au fil - exclusions des messages de service/système - caches natifs à la plateforme nécessaires pour prouver la participation du bot -Bon cas d’usage pour le helper partagé : +Convient bien au helper partagé : - `requireMention` - résultat de mention explicite - liste d’autorisation de mention implicite - contournement de commande -- décision finale d’ignorer +- décision finale d’ignorance Flux recommandé : -1. Calculez les faits de mention locaux. -2. Transmettez ces faits à `resolveInboundMentionDecision({ facts, policy })`. -3. Utilisez `decision.effectiveWasMentioned`, `decision.shouldBypassMention`, et `decision.shouldSkip` dans votre garde d’entrée. +1. Calculez les éléments factuels locaux sur les mentions. +2. Passez ces éléments à `resolveInboundMentionDecision({ facts, policy })`. +3. Utilisez `decision.effectiveWasMentioned`, `decision.shouldBypassMention` et `decision.shouldSkip` dans votre garde d’entrée. ```typescript import { @@ -240,8 +244,8 @@ const decision = resolveInboundMentionDecision({ if (decision.shouldSkip) return; ``` -`api.runtime.channel.mentions` expose les mêmes helpers partagés de mention pour -les plugins de canal intégrés qui dépendent déjà de l’injection runtime : +`api.runtime.channel.mentions` expose les mêmes helpers de mention partagés pour +les Plugins de canal groupés qui dépendent déjà de l’injection d’exécution : - `buildMentionRegexes` - `matchesMentionPatterns` @@ -249,17 +253,17 @@ les plugins de canal intégrés qui dépendent déjà de l’injection runtime : - `implicitMentionKindWhen` - `resolveInboundMentionDecision` -Les anciens helpers `resolveMentionGating*` restent sur +Les anciens helpers `resolveMentionGating*` restent présents dans `openclaw/plugin-sdk/channel-inbound` uniquement comme exports de compatibilité. Le nouveau code doit utiliser `resolveInboundMentionDecision({ facts, policy })`. -## Procédure pas à pas +## Guide pas à pas - Créez les fichiers de plugin standard. Le champ `channel` dans `package.json` est - ce qui en fait un plugin de canal. Pour la surface complète des métadonnées de package, + Créez les fichiers standards du Plugin. Le champ `channel` dans `package.json` + est ce qui en fait un Plugin de canal. Pour la surface complète des métadonnées du package, voir [Plugin Setup and Config](/fr/plugins/sdk-setup#openclaw-channel) : @@ -309,8 +313,8 @@ doit utiliser `resolveInboundMentionDecision({ facts, policy })`. - - L’interface `ChannelPlugin` dispose de nombreuses surfaces d’adaptateur optionnelles. Commencez par + + L’interface `ChannelPlugin` comporte de nombreuses surfaces d’adaptateur optionnelles. Commencez par le minimum — `id` et `setup` — puis ajoutez des adaptateurs selon vos besoins. Créez `src/channel.ts` : @@ -362,7 +366,7 @@ doit utiliser `resolveInboundMentionDecision({ facts, policy })`. }, }), - // Sécurité DM : qui peut envoyer un message au bot + // Sécurité DM : qui peut envoyer des messages au bot security: { dm: { channelKey: "acme-chat", @@ -375,7 +379,7 @@ doit utiliser `resolveInboundMentionDecision({ facts, policy })`. // Appairage : flux d’approbation pour les nouveaux contacts DM pairing: { text: { - idLabel: "Nom d’utilisateur Acme Chat", + idLabel: "nom d’utilisateur Acme Chat", message: "Envoyez ce code pour vérifier votre identité :", notify: async ({ target, code }) => { await acmeChatApi.sendDm(target, `Pairing code: ${code}`); @@ -383,10 +387,10 @@ doit utiliser `resolveInboundMentionDecision({ facts, policy })`. }, }, - // Threading : comment les réponses sont livrées + // Fil des réponses : comment les réponses sont livrées threading: { topLevelReplyToMode: "reply" }, - // Outbound : envoyer des messages vers la plateforme + // Sortant : envoyer des messages vers la plateforme outbound: { attachedResults: { sendText: async (params) => { @@ -407,17 +411,17 @@ doit utiliser `resolveInboundMentionDecision({ facts, policy })`. ``` - Au lieu d’implémenter manuellement des interfaces d’adaptateur de bas niveau, vous transmettez - des options déclaratives et le builder les compose : + Au lieu d’implémenter manuellement des interfaces d’adaptateur de bas niveau, vous passez + des options déclaratives et le constructeur les compose : | Option | Ce qu’elle câble | | --- | --- | - | `security.dm` | Résolveur de sécurité DM à portée, dérivé des champs de configuration | + | `security.dm` | Résolveur de sécurité DM à portée limitée depuis les champs de configuration | | `pairing.text` | Flux d’appairage DM basé sur du texte avec échange de code | - | `threading` | Résolveur de mode de réponse threadée (fixe, à portée de compte, ou personnalisé) | - | `outbound.attachedResults` | Fonctions d’envoi qui renvoient des métadonnées de résultat (ids de message) | + | `threading` | Résolveur de mode de réponse (fixe, à portée de compte ou personnalisé) | + | `outbound.attachedResults` | Fonctions d’envoi qui renvoient des métadonnées de résultat (identifiants de message) | - Vous pouvez aussi transmettre des objets d’adaptateur bruts à la place des options déclaratives + Vous pouvez aussi passer des objets d’adaptateur bruts au lieu des options déclaratives si vous avez besoin d’un contrôle total. @@ -459,14 +463,14 @@ doit utiliser `resolveInboundMentionDecision({ facts, policy })`. }); ``` - Placez les descripteurs CLI appartenant au canal dans `registerCliMetadata(...)` afin qu’OpenClaw - puisse les afficher dans l’aide racine sans activer le runtime complet du canal, - tandis que les chargements complets normaux récupèrent toujours les mêmes descripteurs pour le véritable enregistrement des commandes. - Conservez `registerFull(...)` pour le travail réservé au runtime. - Si `registerFull(...)` enregistre des méthodes RPC gateway, utilisez un - préfixe spécifique au plugin. Les espaces de noms d’administration core (`config.*`, - `exec.approvals.*`, `wizard.*`, `update.*`) restent réservés et - se résolvent toujours vers `operator.admin`. + Placez les descripteurs CLI propres au canal dans `registerCliMetadata(...)` afin qu’OpenClaw + puisse les afficher dans l’aide racine sans activer l’exécution complète du canal, + tandis que les chargements complets normaux récupèrent toujours les mêmes descripteurs pour le véritable enregistrement + des commandes. Réservez `registerFull(...)` au travail réservé à l’exécution. + Si `registerFull(...)` enregistre des méthodes RPC Gateway, utilisez un + préfixe spécifique au Plugin. Les espaces de noms d’administration du cœur (`config.*`, + `exec.approvals.*`, `wizard.*`, `update.*`) restent réservés et se + résolvent toujours vers `operator.admin`. `defineChannelPluginEntry` gère automatiquement la séparation des modes d’enregistrement. Voir [Entry Points](/fr/plugins/sdk-entrypoints#definechannelpluginentry) pour toutes les options. @@ -483,28 +487,28 @@ doit utiliser `resolveInboundMentionDecision({ facts, policy })`. export default defineSetupPluginEntry(acmeChatPlugin); ``` - OpenClaw charge ceci au lieu du point d’entrée complet lorsque le canal est désactivé - ou non configuré. Cela évite de charger du code runtime lourd pendant les flux de configuration. + OpenClaw charge ceci au lieu de l’entrée complète lorsque le canal est désactivé + ou non configuré. Cela évite de charger du code d’exécution lourd pendant les flux de configuration. Voir [Setup and Config](/fr/plugins/sdk-setup#setup-entry) pour plus de détails. - Votre plugin doit recevoir les messages de la plateforme et les transmettre à - OpenClaw. Le modèle typique est un webhook qui vérifie la requête et - la répartit via le gestionnaire entrant de votre canal : + Votre Plugin doit recevoir les messages depuis la plateforme et les transmettre à + OpenClaw. Le modèle habituel est un Webhook qui vérifie la requête et + la distribue via le gestionnaire entrant de votre canal : ```typescript registerFull(api) { api.registerHttpRoute({ path: "/acme-chat/webhook", - auth: "plugin", // authentification gérée par le plugin (vérifiez vous-même les signatures) + auth: "plugin", // authentification gérée par le Plugin (vérifiez vous-même les signatures) handler: async (req, res) => { const event = parseWebhookPayload(req); - // Votre gestionnaire entrant répartit le message vers OpenClaw. + // Votre gestionnaire entrant distribue le message à OpenClaw. // Le câblage exact dépend de votre SDK de plateforme — - // voir un exemple réel dans le package de plugin Microsoft Teams ou Google Chat intégré. + // voir un exemple réel dans le package Plugin groupé Microsoft Teams ou Google Chat. await handleAcmeChatInbound(api, event); res.statusCode = 200; @@ -516,9 +520,9 @@ doit utiliser `resolveInboundMentionDecision({ facts, policy })`. ``` - La gestion des messages entrants est spécifique à chaque canal. Chaque plugin de canal possède - son propre pipeline entrant. Regardez les plugins de canal intégrés - (par exemple le package de plugin Microsoft Teams ou Google Chat) pour voir des modèles réels. + La gestion des messages entrants est spécifique au canal. Chaque Plugin de canal gère + son propre pipeline entrant. Consultez les Plugins de canal groupés + (par exemple le package Plugin Microsoft Teams ou Google Chat) pour voir des modèles réels. @@ -570,48 +574,48 @@ doit utiliser `resolveInboundMentionDecision({ facts, policy })`. ## Structure des fichiers -```text +``` /acme-chat/ ├── package.json # métadonnées openclaw.channel -├── openclaw.plugin.json # manifeste avec schéma de configuration +├── openclaw.plugin.json # Manifeste avec schéma de configuration ├── index.ts # defineChannelPluginEntry ├── setup-entry.ts # defineSetupPluginEntry -├── api.ts # exports publics (optionnel) -├── runtime-api.ts # exports runtime internes (optionnel) +├── api.ts # Exports publics (facultatif) +├── runtime-api.ts # Exports d’exécution internes (facultatif) └── src/ ├── channel.ts # ChannelPlugin via createChatChannelPlugin - ├── channel.test.ts # tests - ├── client.ts # client API de la plateforme - └── runtime.ts # store runtime (si nécessaire) + ├── channel.test.ts # Tests + ├── client.ts # Client API de la plateforme + └── runtime.ts # Stockage d’exécution (si nécessaire) ``` ## Sujets avancés - - Modes de réponse fixes, à portée de compte, ou personnalisés + + Modes de réponse fixes, à portée de compte ou personnalisés - - describeMessageTool et découverte d’actions + + describeMessageTool et découverte des actions inferTargetChatType, looksLikeId, resolveTarget - + TTS, STT, média, sous-agent via api.runtime -Certaines coutures helper intégrées existent encore pour la maintenance des plugins intégrés et -la compatibilité. Elles ne constituent pas le modèle recommandé pour les nouveaux plugins de canal ; -préférez les sous-chemins génériques channel/setup/reply/runtime de la surface -commune du SDK, sauf si vous maintenez directement cette famille de plugins intégrés. +Certaines jonctions de helpers groupés existent encore pour la maintenance et la +compatibilité des Plugins groupés. Elles ne constituent pas le modèle recommandé pour les nouveaux Plugins de canal ; +préférez les sous-chemins génériques channel/setup/reply/runtime de la surface SDK +commune, sauf si vous maintenez directement cette famille de Plugins groupés. ## Étapes suivantes -- [Provider Plugins](/fr/plugins/sdk-provider-plugins) — si votre plugin fournit aussi des modèles -- [SDK Overview](/fr/plugins/sdk-overview) — référence complète des imports de sous-chemins -- [SDK Testing](/fr/plugins/sdk-testing) — utilitaires de test et tests de contrat -- [Plugin Manifest](/fr/plugins/manifest) — schéma complet du manifeste +- [Plugins de fournisseur](/fr/plugins/sdk-provider-plugins) — si votre Plugin fournit aussi des modèles +- [Vue d’ensemble du SDK](/fr/plugins/sdk-overview) — référence complète des imports par sous-chemin +- [Tests du SDK](/fr/plugins/sdk-testing) — utilitaires de test et tests de contrat +- [Manifeste de Plugin](/fr/plugins/manifest) — schéma complet du manifeste diff --git a/docs/fr/reference/RELEASING.md b/docs/fr/reference/RELEASING.md index d47bfebf3..498857969 100644 --- a/docs/fr/reference/RELEASING.md +++ b/docs/fr/reference/RELEASING.md @@ -5,10 +5,10 @@ read_when: summary: Canaux de publication publics, nommage des versions et cadence title: Politique de publication x-i18n: - generated_at: "2026-04-14T06:55:41Z" + generated_at: "2026-04-15T06:56:33Z" model: gpt-5.4 provider: openai - source_hash: 3eaf9f1786b8c9fd4f5a9c657b623cb69d1a485958e1a9b8f108511839b63587 + source_hash: 88724307269ab783a9fbf8a0540fea198d8a3add68457f4e64d5707114fa518c source_path: reference/RELEASING.md workflow: 15 --- @@ -17,124 +17,126 @@ x-i18n: OpenClaw a trois canaux de publication publics : -- stable : versions taguées qui publient sur npm `beta` par défaut, ou sur npm `latest` lorsqu’elles sont explicitement demandées -- beta : tags de préversion qui publient sur npm `beta` +- stable : des publications balisées qui publient vers npm `beta` par défaut, ou vers npm `latest` lorsqu’elles sont demandées explicitement +- beta : des balises de prépublication qui publient vers npm `beta` - dev : la tête mobile de `main` ## Nommage des versions - Version de publication stable : `YYYY.M.D` - - Tag Git : `vYYYY.M.D` + - Balise Git : `vYYYY.M.D` - Version de publication de correction stable : `YYYY.M.D-N` - - Tag Git : `vYYYY.M.D-N` -- Version de préversion beta : `YYYY.M.D-beta.N` - - Tag Git : `vYYYY.M.D-beta.N` -- N’ajoutez pas de zéro de remplissage au mois ou au jour -- `latest` signifie la version npm stable promue actuelle -- `beta` signifie la cible d’installation beta actuelle -- Les versions stables et les versions de correction stable publient sur npm `beta` par défaut ; les opérateurs de publication peuvent cibler `latest` explicitement, ou promouvoir plus tard une build beta validée -- Chaque version d’OpenClaw livre le package npm et l’app macOS ensemble + - Balise Git : `vYYYY.M.D-N` +- Version de prépublication bêta : `YYYY.M.D-beta.N` + - Balise Git : `vYYYY.M.D-beta.N` +- Ne mettez pas de zéro non significatif pour le mois ou le jour +- `latest` signifie la publication npm stable promue actuelle +- `beta` signifie la cible d’installation bêta actuelle +- Les publications stables et les publications de correction stable publient vers npm `beta` par défaut ; les opérateurs de publication peuvent cibler `latest` explicitement, ou promouvoir plus tard une build bêta validée +- Chaque publication OpenClaw livre le package npm et l’app macOS ensemble ## Cadence de publication - Les publications passent d’abord par beta -- Stable ne suit qu’une fois la dernière beta validée -- La procédure de publication détaillée, les approbations, les identifiants et les notes de récupération sont réservés aux mainteneurs +- stable ne suit qu’après validation de la dernière bêta +- La procédure de publication détaillée, les approbations, les identifiants et les notes de reprise sont réservés aux mainteneurs ## Vérifications préalables à la publication -- Exécutez `pnpm build && pnpm ui:build` avant `pnpm release:check` afin que les artefacts de publication `dist/*` attendus et le bundle de l’UI de contrôle existent pour l’étape de validation du pack -- Exécutez `pnpm release:check` avant chaque publication taguée -- Les vérifications de publication s’exécutent maintenant dans un workflow manuel séparé : +- Exécutez `pnpm build && pnpm ui:build` avant `pnpm release:check` afin que les artefacts de publication attendus `dist/*` et le bundle de l’interface Control UI existent pour l’étape de validation du pack +- Exécutez `pnpm release:check` avant chaque publication balisée +- Les vérifications de publication s’exécutent désormais dans un workflow manuel distinct : `OpenClaw Release Checks` -- Cette séparation est intentionnelle : elle garde le vrai chemin de publication npm court, déterministe et centré sur les artefacts, tandis que les vérifications live plus lentes restent dans leur propre canal pour ne pas retarder ou bloquer la publication -- Les vérifications de publication doivent être déclenchées depuis la ref de workflow `main` afin que la logique du workflow et les secrets restent canoniques -- Ce workflow accepte soit un tag de publication existant, soit le SHA de commit `main` complet actuel à 40 caractères -- En mode SHA de commit, il n’accepte que le HEAD actuel de `origin/main` ; utilisez un tag de publication pour les anciens commits de publication -- La pré-vérification en validation seule de `OpenClaw NPM Release` accepte également le SHA de commit `main` complet actuel à 40 caractères sans nécessiter de tag poussé -- Ce chemin SHA est réservé à la validation et ne peut pas être promu en véritable publication -- En mode SHA, le workflow synthétise `v` uniquement pour la vérification des métadonnées du package ; la vraie publication exige toujours un vrai tag de publication -- Les deux workflows gardent le vrai chemin de publication et de promotion sur des runners hébergés par GitHub, tandis que le chemin de validation non mutatif peut utiliser les runners Linux Blacksmith plus grands +- La validation d’exécution d’installation et de mise à niveau multi-OS est déclenchée depuis le workflow appelant privé + `openclaw/releases-private/.github/workflows/openclaw-cross-os-release-checks.yml`, + qui invoque le workflow public réutilisable + `.github/workflows/openclaw-cross-os-release-checks-reusable.yml` +- Cette séparation est intentionnelle : elle permet de garder le chemin réel de publication npm court, déterministe et centré sur les artefacts, tandis que les vérifications live plus lentes restent dans leur propre canal afin de ne pas ralentir ni bloquer la publication +- Les vérifications de publication doivent être déclenchées depuis la référence de workflow `main` afin que la logique du workflow et les secrets restent canoniques +- Ce workflow accepte soit une balise de publication existante, soit le SHA de commit complet actuel de `main` sur 40 caractères +- En mode SHA de commit, il n’accepte que la HEAD actuelle de `origin/main` ; utilisez une balise de publication pour les anciens commits de publication +- Le contrôle préalable en validation seule de `OpenClaw NPM Release` accepte également le SHA de commit complet actuel de `main` sur 40 caractères sans exiger de balise déjà poussée +- Ce chemin SHA est uniquement destiné à la validation et ne peut pas être promu en publication réelle +- En mode SHA, le workflow synthétise `v` uniquement pour la vérification des métadonnées du package ; la publication réelle exige toujours une véritable balise de publication +- Les deux workflows conservent le vrai chemin de publication et de promotion sur des runners hébergés par GitHub, tandis que le chemin de validation non mutatif peut utiliser les runners Linux Blacksmith plus grands - Ce workflow exécute `OPENCLAW_LIVE_TEST=1 OPENCLAW_LIVE_CACHE_TEST=1 pnpm test:live:cache` - en utilisant à la fois les secrets de workflow `OPENAI_API_KEY` et `ANTHROPIC_API_KEY` -- La pré-vérification de publication npm n’attend plus le canal séparé des vérifications de publication + en utilisant les secrets de workflow `OPENAI_API_KEY` et `ANTHROPIC_API_KEY` +- Le contrôle préalable de publication npm n’attend plus le canal distinct des vérifications de publication - Exécutez `RELEASE_TAG=vYYYY.M.D node --import tsx scripts/openclaw-npm-release-check.ts` - (ou le tag beta/correction correspondant) avant l’approbation + (ou la balise bêta/correction correspondante) avant l’approbation - Après la publication npm, exécutez `node --import tsx scripts/openclaw-npm-postpublish-verify.ts YYYY.M.D` - (ou la version beta/correction correspondante) pour vérifier le chemin d’installation du registre publié dans un préfixe temporaire frais -- L’automatisation de publication des mainteneurs utilise désormais le modèle pré-vérification puis promotion : - - la vraie publication npm doit réussir avec un `preflight_run_id` de pré-vérification réussi + (ou la version bêta/correction correspondante) pour vérifier le chemin d’installation publié depuis le registre dans un préfixe temporaire propre +- L’automatisation de publication des mainteneurs utilise désormais le flux contrôle préalable puis promotion : + - la vraie publication npm doit réussir avec un `preflight_run_id` npm valide - les publications npm stables ciblent `beta` par défaut - - la publication npm stable peut cibler `latest` explicitement via une entrée du workflow - - la promotion npm stable de `beta` vers `latest` reste disponible en mode manuel explicite dans le workflow de confiance `OpenClaw NPM Release` - - les publications stables directes peuvent également exécuter un mode explicite de synchronisation des dist-tags qui fait pointer `latest` et `beta` vers la version stable déjà publiée - - ces modes de dist-tag nécessitent toujours un `NPM_TOKEN` valide dans l’environnement `npm-release`, car la gestion des `dist-tag` npm est distincte de la publication de confiance - - la publication publique `macOS Release` est réservée à la validation - - la vraie publication privée mac doit réussir avec des `preflight_run_id` et `validate_run_id` privés mac réussis + - la publication npm stable peut cibler `latest` explicitement via une entrée de workflow + - la mutation par jeton des dist-tags npm se trouve désormais dans + `openclaw/releases-private/.github/workflows/openclaw-npm-dist-tags.yml` + pour des raisons de sécurité, car `npm dist-tag add` exige toujours `NPM_TOKEN` alors que le dépôt public conserve une publication OIDC uniquement + - la `macOS Release` publique est uniquement destinée à la validation + - la véritable publication privée mac doit réussir avec des `preflight_run_id` et `validate_run_id` privés valides - les vrais chemins de publication promeuvent des artefacts préparés au lieu de les reconstruire une nouvelle fois -- Pour les versions de correction stable comme `YYYY.M.D-N`, le vérificateur post-publication vérifie également le même chemin de mise à niveau en préfixe temporaire de `YYYY.M.D` vers `YYYY.M.D-N`, afin que les corrections de publication ne puissent pas laisser silencieusement les anciennes installations globales sur la charge utile stable de base -- La pré-vérification de publication npm échoue en mode fermé sauf si le tarball inclut à la fois `dist/control-ui/index.html` et une charge utile non vide `dist/control-ui/assets/`, afin d’éviter de livrer à nouveau un tableau de bord navigateur vide -- `pnpm test:install:smoke` applique également le budget `unpackedSize` du `npm pack` sur le tarball candidat à la mise à jour, afin que l’e2e de l’installateur détecte toute augmentation accidentelle de taille du pack avant le chemin de publication -- Si le travail de publication a touché la planification CI, les manifestes de timing des extensions ou les matrices de test des extensions, régénérez et examinez les sorties de matrice du workflow `checks-node-extensions` gérées par le planificateur depuis `.github/workflows/ci.yml` avant l’approbation, afin que les notes de publication ne décrivent pas une disposition CI obsolète -- La préparation d’une version macOS stable inclut également les surfaces de mise à jour : +- Pour les publications de correction stable comme `YYYY.M.D-N`, le vérificateur post-publication contrôle également le même chemin de mise à niveau en préfixe temporaire de `YYYY.M.D` vers `YYYY.M.D-N` afin que les corrections de publication ne puissent pas laisser silencieusement d’anciennes installations globales sur la charge utile stable de base +- Le contrôle préalable de publication npm échoue par défaut sauf si le tarball inclut à la fois `dist/control-ui/index.html` et une charge utile non vide `dist/control-ui/assets/` afin d’éviter d’expédier à nouveau un tableau de bord navigateur vide +- `pnpm test:install:smoke` applique aussi le budget `unpackedSize` du pack npm au tarball de mise à jour candidat, afin que l’E2E de l’installateur détecte toute augmentation accidentelle de taille du pack avant le chemin de publication +- Si le travail de publication a touché à la planification CI, aux manifestes de timing des extensions ou aux matrices de test des extensions, régénérez et examinez les sorties de matrice de workflow `checks-node-extensions` gérées par le planificateur à partir de `.github/workflows/ci.yml` avant l’approbation afin que les notes de publication ne décrivent pas une disposition CI obsolète +- L’état de préparation d’une publication macOS stable inclut aussi les surfaces de mise à jour : - la publication GitHub doit finir avec les fichiers empaquetés `.zip`, `.dmg` et `.dSYM.zip` - - `appcast.xml` sur `main` doit pointer vers le nouveau zip stable après publication - - l’app empaquetée doit conserver un identifiant de bundle non debug, une URL de flux Sparkle non vide et un `CFBundleVersion` au moins égal au plancher canonique de build Sparkle pour cette version + - `appcast.xml` sur `main` doit pointer vers le nouveau zip stable après la publication + - l’app empaquetée doit conserver un identifiant de bundle non debug, une URL de flux Sparkle non vide et un `CFBundleVersion` supérieur ou égal au plancher canonique de build Sparkle pour cette version de publication ## Entrées du workflow NPM `OpenClaw NPM Release` accepte ces entrées contrôlées par l’opérateur : -- `tag` : tag de publication requis tel que `v2026.4.2`, `v2026.4.2-1` ou `v2026.4.2-beta.1` ; lorsque `preflight_only=true`, il peut aussi s’agir du SHA de commit `main` complet actuel à 40 caractères pour une pré-vérification en validation seule +- `tag` : balise de publication requise telle que `v2026.4.2`, `v2026.4.2-1`, ou `v2026.4.2-beta.1` ; lorsque `preflight_only=true`, cela peut aussi être le SHA de commit complet actuel de `main` sur 40 caractères pour un contrôle préalable de validation seule - `preflight_only` : `true` pour validation/build/package uniquement, `false` pour le vrai chemin de publication -- `preflight_run_id` : requis sur le vrai chemin de publication afin que le workflow réutilise le tarball préparé depuis l’exécution de pré-vérification réussie -- `npm_dist_tag` : tag cible npm pour le chemin de publication ; vaut `beta` par défaut -- `promote_beta_to_latest` : `true` pour ignorer la publication et déplacer une build stable `beta` déjà publiée vers `latest` -- `sync_stable_dist_tags` : `true` pour ignorer la publication et faire pointer `latest` et `beta` vers une version stable déjà publiée +- `preflight_run_id` : requis pour le vrai chemin de publication afin que le workflow réutilise le tarball préparé depuis l’exécution de contrôle préalable réussie +- `npm_dist_tag` : dist-tag npm cible pour le chemin de publication ; la valeur par défaut est `beta` `OpenClaw Release Checks` accepte ces entrées contrôlées par l’opérateur : -- `ref` : tag de publication existant ou SHA de commit `main` complet actuel à 40 caractères à valider +- `ref` : balise de publication existante ou SHA de commit complet actuel de `main` sur 40 caractères à valider Règles : -- Les tags stables et de correction peuvent publier vers `beta` ou `latest` -- Les tags de préversion beta ne peuvent publier que vers `beta` +- Les balises stables et de correction peuvent publier vers `beta` ou `latest` +- Les balises de prépublication bêta ne peuvent publier que vers `beta` - L’entrée SHA de commit complet n’est autorisée que lorsque `preflight_only=true` -- Le mode SHA de commit des vérifications de publication exige également le HEAD actuel de `origin/main` -- Le vrai chemin de publication doit utiliser le même `npm_dist_tag` que celui utilisé pendant la pré-vérification ; le workflow vérifie ces métadonnées avant de poursuivre la publication -- Le mode promotion doit utiliser un tag stable ou de correction, `preflight_only=false`, un `preflight_run_id` vide et `npm_dist_tag=beta` -- Le mode de synchronisation des dist-tags doit utiliser un tag stable ou de correction, `preflight_only=false`, un `preflight_run_id` vide, `npm_dist_tag=latest` et `promote_beta_to_latest=false` -- Les modes promotion et synchronisation des dist-tags exigent également un `NPM_TOKEN` valide, car `npm dist-tag add` nécessite toujours une authentification npm classique ; la publication de confiance couvre uniquement le chemin de publication du package +- Le mode SHA de commit des vérifications de publication exige également la HEAD actuelle de `origin/main` +- Le vrai chemin de publication doit utiliser le même `npm_dist_tag` que celui utilisé pendant le contrôle préalable ; le workflow vérifie ces métadonnées avant de poursuivre la publication ## Séquence de publication npm stable Lors de la création d’une publication npm stable : 1. Exécutez `OpenClaw NPM Release` avec `preflight_only=true` - - Avant qu’un tag n’existe, vous pouvez utiliser le SHA de commit `main` complet actuel pour un essai à sec en validation seule du workflow de pré-vérification + - Avant qu’une balise n’existe, vous pouvez utiliser le SHA de commit complet actuel de `main` pour une exécution à blanc de validation seule du workflow de contrôle préalable 2. Choisissez `npm_dist_tag=beta` pour le flux normal beta-first, ou `latest` uniquement lorsque vous souhaitez intentionnellement une publication stable directe -3. Exécutez `OpenClaw Release Checks` séparément avec le même tag ou le SHA complet actuel de `main` lorsque vous voulez une couverture live du cache de prompt +3. Exécutez `OpenClaw Release Checks` séparément avec la même balise ou le SHA complet actuel de `main` lorsque vous voulez une couverture live du cache de prompt - Cette séparation est intentionnelle afin que la couverture live reste disponible sans recoupler des vérifications longues ou instables au workflow de publication 4. Enregistrez le `preflight_run_id` réussi 5. Exécutez à nouveau `OpenClaw NPM Release` avec `preflight_only=false`, le même `tag`, le même `npm_dist_tag` et le `preflight_run_id` enregistré -6. Si la publication est arrivée sur `beta`, exécutez plus tard `OpenClaw NPM Release` avec le même `tag` stable, `promote_beta_to_latest=true`, `preflight_only=false`, un `preflight_run_id` vide et `npm_dist_tag=beta` lorsque vous souhaitez déplacer cette build publiée vers `latest` -7. Si la publication a été intentionnellement publiée directement sur `latest` et que `beta` doit suivre la même build stable, exécutez `OpenClaw NPM Release` avec le même `tag` stable, `sync_stable_dist_tags=true`, `promote_beta_to_latest=false`, `preflight_only=false`, un `preflight_run_id` vide et `npm_dist_tag=latest` +6. Si la publication a atterri sur `beta`, utilisez le workflow privé + `openclaw/releases-private/.github/workflows/openclaw-npm-dist-tags.yml` + pour promouvoir cette version stable de `beta` vers `latest` +7. Si la publication a été intentionnellement publiée directement vers `latest` et que `beta` doit suivre immédiatement avec la même build stable, utilisez ce même workflow privé pour faire pointer les deux dist-tags vers la version stable, ou laissez sa synchronisation d’autoréparation planifiée déplacer `beta` plus tard -Les modes promotion et synchronisation des dist-tags nécessitent toujours l’approbation de l’environnement `npm-release` et un `NPM_TOKEN` valide accessible à cette exécution du workflow. +La mutation des dist-tags se trouve dans le dépôt privé pour des raisons de sécurité, car elle exige toujours `NPM_TOKEN`, tandis que le dépôt public conserve une publication OIDC uniquement. -Cela permet de garder à la fois le chemin de publication directe et le chemin de promotion beta-first documentés et visibles pour l’opérateur. +Cela permet de documenter et de rendre visible aux opérateurs à la fois le chemin de publication directe et le chemin de promotion beta-first. ## Références publiques - [`.github/workflows/openclaw-npm-release.yml`](https://github.com/openclaw/openclaw/blob/main/.github/workflows/openclaw-npm-release.yml) - [`.github/workflows/openclaw-release-checks.yml`](https://github.com/openclaw/openclaw/blob/main/.github/workflows/openclaw-release-checks.yml) +- [`.github/workflows/openclaw-cross-os-release-checks-reusable.yml`](https://github.com/openclaw/openclaw/blob/main/.github/workflows/openclaw-cross-os-release-checks-reusable.yml) - [`scripts/openclaw-npm-release-check.ts`](https://github.com/openclaw/openclaw/blob/main/scripts/openclaw-npm-release-check.ts) - [`scripts/package-mac-dist.sh`](https://github.com/openclaw/openclaw/blob/main/scripts/package-mac-dist.sh) - [`scripts/make_appcast.sh`](https://github.com/openclaw/openclaw/blob/main/scripts/make_appcast.sh) -Les mainteneurs utilisent la documentation privée de publication dans +Les mainteneurs utilisent la documentation de publication privée dans [`openclaw/maintainers/release/README.md`](https://github.com/openclaw/maintainers/blob/main/release/README.md) comme véritable runbook. diff --git a/docs/fr/reference/secretref-credential-surface.md b/docs/fr/reference/secretref-credential-surface.md index 93dd460cd..3a2b8b70a 100644 --- a/docs/fr/reference/secretref-credential-surface.md +++ b/docs/fr/reference/secretref-credential-surface.md @@ -1,15 +1,15 @@ --- read_when: - - Vérifier la couverture des identifiants SecretRef + - Vérification de la couverture des identifiants SecretRef - Vérifier si un identifiant est éligible à `secrets configure` ou `secrets apply` - - Vérifier pourquoi un identifiant est en dehors de la surface prise en charge -summary: Surface canonique des identifiants SecretRef pris en charge et non pris en charge + - Vérifier pourquoi un identifiant est hors de la surface prise en charge +summary: Surface canonique prise en charge ou non prise en charge des identifiants SecretRef title: Surface des identifiants SecretRef x-i18n: - generated_at: "2026-04-07T06:53:54Z" + generated_at: "2026-04-15T06:57:09Z" model: gpt-5.4 provider: openai - source_hash: 211f4b504c5808f7790683066fc2c8b700c705c598f220a264daf971b81cc593 + source_hash: dd0b9c379236b17a72f552d6360b8b5a2269009e019c138c6bb50f4f7328ddaf source_path: reference/secretref-credential-surface.md workflow: 15 --- @@ -18,10 +18,10 @@ x-i18n: Cette page définit la surface canonique des identifiants SecretRef. -Portée visée : +Intention du périmètre : -- Dans le périmètre : identifiants strictement fournis par l’utilisateur qu’OpenClaw ne génère ni ne fait tourner. -- Hors périmètre : identifiants générés ou renouvelés à l’exécution, matériel de rafraîchissement OAuth et artefacts de type session. +- Dans le périmètre : strictement les identifiants fournis par l’utilisateur qu’OpenClaw ne crée ni ne fait tourner. +- Hors périmètre : les identifiants créés à l’exécution ou rotatifs, le matériel de rafraîchissement OAuth et les artefacts de type session. ## Identifiants pris en charge @@ -49,6 +49,7 @@ Portée visée : - `messages.tts.providers.*.apiKey` - `tools.web.fetch.firecrawl.apiKey` - `plugins.entries.brave.config.webSearch.apiKey` +- `plugins.entries.exa.config.webSearch.apiKey` - `plugins.entries.google.config.webSearch.apiKey` - `plugins.entries.xai.config.webSearch.apiKey` - `plugins.entries.moonshot.config.webSearch.apiKey` @@ -107,8 +108,8 @@ Portée visée : - `channels.zalo.webhookSecret` - `channels.zalo.accounts.*.botToken` - `channels.zalo.accounts.*.webhookSecret` -- `channels.googlechat.serviceAccount` via le champ frère `serviceAccountRef` (exception de compatibilité) -- `channels.googlechat.accounts.*.serviceAccount` via le champ frère `serviceAccountRef` (exception de compatibilité) +- `channels.googlechat.serviceAccount` via le `serviceAccountRef` frère (exception de compatibilité) +- `channels.googlechat.accounts.*.serviceAccount` via le `serviceAccountRef` frère (exception de compatibilité) ### Cibles `auth-profiles.json` (`secrets configure` + `secrets apply` + `secrets audit`) @@ -120,16 +121,16 @@ Portée visée : Remarques : - Les cibles de plan de profil d’authentification nécessitent `agentId`. -- Les entrées de plan ciblent `profiles.*.key` / `profiles.*.token` et écrivent les références sœurs (`keyRef` / `tokenRef`). +- Les entrées du plan ciblent `profiles.*.key` / `profiles.*.token` et écrivent les références sœurs (`keyRef` / `tokenRef`). - Les références de profil d’authentification sont incluses dans la résolution à l’exécution et dans la couverture d’audit. -- Garde-fou de politique OAuth : `auth.profiles..mode = "oauth"` ne peut pas être combiné avec des entrées SecretRef pour ce profil. Le démarrage/rechargement et la résolution du profil d’authentification échouent immédiatement lorsque cette politique est violée. -- Pour les fournisseurs de modèles gérés par SecretRef, les entrées générées `agents/*/agent/models.json` conservent des marqueurs non secrets (et non des valeurs secrètes résolues) pour les surfaces `apiKey`/en-têtes. -- La persistance des marqueurs fait autorité côté source : OpenClaw écrit les marqueurs depuis l’instantané actif de la configuration source (avant résolution), et non depuis les valeurs secrètes résolues à l’exécution. +- Garde de politique OAuth : `auth.profiles..mode = "oauth"` ne peut pas être combiné avec des entrées SecretRef pour ce profil. Le démarrage/rechargement et la résolution du profil d’authentification échouent immédiatement si cette politique est violée. +- Pour les fournisseurs de modèles gérés par SecretRef, les entrées générées `agents/*/agent/models.json` conservent des marqueurs non secrets (et non les valeurs secrètes résolues) pour les surfaces `apiKey`/en-tête. +- La persistance des marqueurs fait autorité depuis la source : OpenClaw écrit les marqueurs à partir de l’instantané de configuration source actif (avant résolution), et non à partir des valeurs secrètes résolues à l’exécution. - Pour la recherche web : - En mode fournisseur explicite (`tools.web.search.provider` défini), seule la clé du fournisseur sélectionné est active. - - En mode auto (`tools.web.search.provider` non défini), seule la première clé de fournisseur qui se résout selon la priorité est active. - - En mode auto, les références des fournisseurs non sélectionnés sont traitées comme inactives jusqu’à leur sélection. - - Les anciens chemins de fournisseur `tools.web.search.*` se résolvent encore pendant la fenêtre de compatibilité, mais la surface canonique SecretRef est `plugins.entries..config.webSearch.*`. + - En mode automatique (`tools.web.search.provider` non défini), seule la première clé de fournisseur résolue selon la priorité est active. + - En mode automatique, les références des fournisseurs non sélectionnés sont traitées comme inactives jusqu’à leur sélection. + - Les anciens chemins de fournisseur `tools.web.search.*` continuent à être résolus pendant la fenêtre de compatibilité, mais la surface canonique SecretRef est `plugins.entries..config.webSearch.*`. ## Identifiants non pris en charge @@ -151,4 +152,4 @@ Les identifiants hors périmètre incluent : Justification : -- Ces identifiants appartiennent à des classes générées, renouvelées, porteuses de session ou durables OAuth qui ne correspondent pas à une résolution SecretRef externe en lecture seule. +- Ces identifiants appartiennent à des classes créées, rotatives, porteuses de session ou durables OAuth qui ne correspondent pas à la résolution SecretRef externe en lecture seule. diff --git a/docs/fr/start/showcase.md b/docs/fr/start/showcase.md index 1120dad96..8e1db7b79 100644 --- a/docs/fr/start/showcase.md +++ b/docs/fr/start/showcase.md @@ -1,146 +1,173 @@ --- +description: Real-world OpenClaw projects from the community read_when: - - Vous cherchez des exemples concrets d'utilisation d'OpenClaw - - Vous mettez à jour les projets phares de la communauté -summary: Projets et intégrations créés par la communauté et propulsés par OpenClaw + - Vous cherchez des exemples réels d’utilisation d’OpenClaw + - Mise à jour des projets communautaires mis en avant +summary: Projets et intégrations créés par la communauté, propulsés par OpenClaw title: Vitrine x-i18n: - generated_at: "2026-04-05T12:55:52Z" + generated_at: "2026-04-15T06:57:08Z" model: gpt-5.4 provider: openai - source_hash: 2917e9a476ef527ddb3e51c610bbafbd145e705c9cc29f191639fb63d238ef70 + source_hash: 797d0b85c9eca920240c79d870eb9636216714f3eba871c5ebd0f7f40cf7bbf1 source_path: start/showcase.md workflow: 15 --- + + # Vitrine -De vrais projets issus de la communauté. Découvrez ce que les gens construisent avec OpenClaw. +
+

Conçu dans des chats, des terminaux, des navigateurs et des salons

+

+ Les projets OpenClaw ne sont pas des démos gadgets. Des gens livrent des boucles de revue de PR, des applications mobiles, de la domotique, + des systèmes vocaux, des outils de développement et des flux de travail riches en mémoire depuis les canaux qu’ils utilisent déjà. +

+ +
+
+ Créations natives du chat + Telegram, WhatsApp, Discord, Beeper, chat web et flux de travail orientés terminal. +
+
+ Automatisation réelle + Réservation, achats, support, reporting et contrôle du navigateur sans attendre une API. +
+
+ Local + monde physique + Imprimantes, aspirateurs, caméras, données de santé, systèmes domestiques et bases de connaissances personnelles. +
+
+
-**Vous voulez figurer ici ?** Partagez votre projet dans [#self-promotion sur Discord](https://discord.gg/clawd) ou [identifiez @openclaw sur X](https://x.com/openclaw). +**Vous voulez être mis en avant ?** Partagez votre projet dans [#self-promotion sur Discord](https://discord.gg/clawd) ou [identifiez @openclaw sur X](https://x.com/openclaw). -## 🎥 OpenClaw en action - -Visite guidée complète de l'installation (28 min) par VelvetShark. - -
-