Présentation des messages
La présentation des messages est le contrat partagé d’OpenClaw pour les interfaces de chat sortantes enrichies. Elle permet aux agents, aux commandes CLI, aux flux d’approbation et aux plugins de décrire une seule fois l’intention du message, tandis que chaque plugin de canal effectue le rendu dans la meilleure forme native possible. Utilisez la présentation pour une interface de message portable :- sections de texte
- petit texte de contexte/pied de page
- séparateurs
- boutons
- menus de sélection
- titre et ton de carte
components pour Discord, blocks pour Slack,
buttons pour Telegram, card pour Teams ou card pour Feishu dans l’outil de message
partagé. Ce sont des sorties de moteur de rendu possédées par le plugin de canal.
Contrat
Les auteurs de plugins importent le contrat public depuis :valueest une valeur d’action applicative reroutée via le chemin d’interaction existant du canal lorsque le canal prend en charge les contrôles cliquables.urlest un bouton de lien. Il peut exister sansvalue.labelest requis et est aussi utilisé dans le texte de repli.styleest indicatif. Les moteurs de rendu doivent mapper les styles non pris en charge vers une valeur sûre par défaut, sans faire échouer l’envoi.
options[].valueest la valeur applicative sélectionnée.placeholderest indicatif et peut être ignoré par les canaux sans prise en charge native des sélections.- Si un canal ne prend pas en charge les sélections, le texte de repli liste les libellés.
Exemples côté producteur
Carte simple :Contrat du moteur de rendu
Les plugins de canal déclarent la prise en charge du rendu sur leur adaptateur sortant :Flux de rendu du core
Lorsqu’unReplyPayload ou une action de message inclut presentation, le core :
- normalise la charge utile de présentation.
- résout l’adaptateur sortant du canal cible.
- lit
presentationCapabilities. - appelle
renderPresentationlorsque l’adaptateur peut rendre la charge utile. - revient à un texte conservateur lorsque l’adaptateur est absent ou ne peut pas effectuer le rendu.
- envoie la charge utile résultante via le chemin normal de distribution du canal.
- applique les métadonnées de distribution comme
delivery.pinaprès le premier message envoyé avec succès.
Règles de dégradation
La présentation doit pouvoir être envoyée en toute sécurité sur des canaux limités. Le texte de repli inclut :titlecomme première ligne- les blocs
textcomme paragraphes normaux - les blocs
contextcomme lignes de contexte compactes - les blocs
dividercomme séparateur visuel - les libellés des boutons, y compris les URL pour les boutons de lien
- les libellés des options de sélection
- Telegram avec les boutons inline désactivés envoie un texte de repli.
- Un canal sans prise en charge des sélections liste les options de sélection en texte.
- Un bouton à URL seule devient soit un bouton de lien natif, soit une ligne URL de repli.
- Les échecs d’épinglage facultatifs ne font pas échouer le message distribué.
delivery.pin.required: true ; si un épinglage est demandé comme
obligatoire et que le canal ne peut pas épingler le message envoyé, la distribution signale un échec.
Correspondance par provider
Moteurs de rendu intégrés actuels :| Canal | Cible de rendu native | Remarques |
|---|---|---|
| Discord | Components et conteneurs de composants | Préserve l’ancien channelData.discord.components pour les producteurs existants de charges utiles natives au provider, mais les nouveaux envois partagés doivent utiliser presentation. |
| Slack | Block Kit | Préserve l’ancien channelData.slack.blocks pour les producteurs existants de charges utiles natives au provider, mais les nouveaux envois partagés doivent utiliser presentation. |
| Telegram | Texte plus claviers inline | Les boutons/sélections nécessitent la capacité de boutons inline pour la surface cible ; sinon, un texte de repli est utilisé. |
| Mattermost | Texte plus props interactives | Les autres blocs se dégradent en texte. |
| Microsoft Teams | Adaptive Cards | Le texte message brut est inclus avec la carte lorsque les deux sont fournis. |
| Feishu | Cartes interactives | L’en-tête de carte peut utiliser title ; le corps évite de dupliquer ce titre. |
| Canaux simples | Texte de repli | Les canaux sans moteur de rendu obtiennent tout de même une sortie lisible. |
Présentation vs InteractiveReply
InteractiveReply est l’ancien sous-ensemble interne utilisé par les helpers d’approbation et d’interaction.
Il prend en charge :
- texte
- boutons
- sélections
MessagePresentation est le contrat partagé canonique d’envoi. Il ajoute :
- titre
- ton
- contexte
- séparateur
- boutons à URL seule
- métadonnées de distribution génériques via
ReplyPayload.delivery
openclaw/plugin-sdk/interactive-runtime lors du pont avec l’ancien
code :
MessagePresentation.
Épinglage de distribution
L’épinglage est un comportement de distribution, pas de présentation. Utilisezdelivery.pin au lieu de
champs natifs au provider comme channelData.telegram.pin.
Sémantique :
pin: trueépingle le premier message distribué avec succès.pin.notifyvautfalsepar défaut.pin.requiredvautfalsepar défaut.- Les échecs d’épinglage facultatifs se dégradent et laissent le message envoyé intact.
- Les échecs d’épinglage obligatoires font échouer la distribution.
- Les messages découpés en blocs épinglent le premier segment distribué, pas le segment final.
pin, unpin et pins existent toujours pour les
messages existants lorsque le provider prend en charge ces opérations.
Checklist pour les auteurs de plugins
- Déclarez
presentationdepuisdescribeMessageTool(...)lorsque le canal peut rendre ou dégrader en toute sécurité une présentation sémantique. - Ajoutez
presentationCapabilitiesà l’adaptateur sortant d’exécution. - Implémentez
renderPresentationdans le code d’exécution, pas dans le code d’initialisation du Plugin de plan de contrôle. - Gardez les bibliothèques d’interface natives hors des chemins chauds de configuration/catalogue.
- Préservez les limites de la plateforme dans le moteur de rendu et les tests.
- Ajoutez des tests de repli pour les boutons, sélections, boutons URL, duplication titre/texte non pris en charge,
et les envois mixtes
messagepluspresentation. - Ajoutez la prise en charge de l’épinglage de distribution via
deliveryCapabilities.pinetpinDeliveredMessageuniquement lorsque le provider peut épingler l’ID du message envoyé. - N’exposez pas de nouveaux champs natifs au provider pour carte/bloc/composant/bouton via le schéma partagé des actions de message.