- Textabschnitte
- kleiner Kontext-/Footer-Text
- Trennlinien
- Buttons
- Auswahlmenüs
- Kartentitel und Ton
components, Slack-blocks, Telegram-buttons, Teams-card oder Feishu-card hinzu. Diese sind Renderer-Ausgaben, die dem Channel-Plugin gehören.
Contract
Plugin-Autoren importieren den öffentlichen Contract aus:action.type: "command"führt einen nativen Slash-Befehl über den Befehlspfad des Core aus. Verwenden Sie dies für integrierte Befehls-Buttons und Menüs.action.type: "callback"transportiert opake Plugin-Daten über den Interaktionspfad des Channels. Channel-Plugins dürfen Callback-Daten nicht als Slash-Befehle neu interpretieren.valueist der veraltete opake Callback-Wert. Neue Controls solltenactionverwenden, damit Channel-Plugins Befehle und Callbacks zuordnen können, ohne aus Text raten zu müssen.urlist ein Link-Button. Er kann ohnevalueexistieren.webAppbeschreibt einen channel-nativen Web-App-Button. Telegram rendert dies alsweb_appund unterstützt es nur in privaten Chats.web_appwird aus Kompatibilitätsgründen weiterhin in lockeren JSON-Payloads akzeptiert, TypeScript-Produzenten sollten jedochwebAppverwenden.labelist erforderlich und wird auch im Text-Fallback verwendet.styleist beratend. Renderer sollten nicht unterstützte Styles auf einen sicheren Standard abbilden, nicht den Versand fehlschlagen lassen.priorityist optional. Wenn ein Channel Aktionslimits angibt und Controls verworfen werden müssen, behält Core zuerst Buttons mit höherer Priorität bei und bewahrt die ursprüngliche Reihenfolge unter Buttons gleicher Priorität. Wenn alle Controls passen, bleibt die authored Reihenfolge erhalten.disabledist optional. Channels müssen sich mitsupportsDisableddafür anmelden; andernfalls stuft Core das deaktivierte Control auf nicht interaktiven Fallback-Text zurück.reusableist optional. Channels, die wiederverwendbare native Callbacks unterstützen, können die Aktion nach einer erfolgreichen Interaktion verfügbar halten. Verwenden Sie dies für wiederholbare oder idempotente Aktionen wie Aktualisieren, Inspizieren oder weitere Details; lassen Sie es für normale einmalige Approvals und destruktive Aktionen unset.
options[].actionhat dieselbe Befehls-/Callback-Bedeutung wie Button-action.options[].valueist der veraltete ausgewählte Anwendungswert.placeholderist beratend und kann von Channels ohne native Select-Unterstützung ignoriert werden.- Wenn ein Channel Selects nicht unterstützt, listet Fallback-Text die Labels auf.
Producer-Beispiele
Einfache Karte:Renderer-Contract
Channel-Plugins deklarieren Render-Unterstützung auf ihrem ausgehenden Adapter:limits beschreiben die generische Hülle, die Core vor dem Aufruf des Renderers anpassen kann:
Core-Render-Flow
Wenn einReplyPayload oder eine Nachrichtenaktion presentation enthält, führt Core Folgendes aus:
- Normalisiert den Presentation-Payload.
- Löst den ausgehenden Adapter des Ziel-Channels auf.
- Liest
presentationCapabilities. - Wendet generische Capability-Limits wie Aktionsanzahl, Label-Länge und Anzahl der Select-Optionen an, wenn der Adapter sie angibt.
- Ruft
renderPresentationauf, wenn der Adapter den Payload rendern kann. - Fällt auf konservativen Text zurück, wenn der Adapter fehlt oder nicht rendern kann.
- Sendet den resultierenden Payload über den normalen Zustellungspfad des Channels.
- Wendet Zustellungsmetadaten wie
delivery.pinnach der ersten erfolgreich gesendeten Nachricht an.
Degradationsregeln
Presentation muss auf eingeschränkten Channels sicher zu senden sein. Fallback-Text enthält:titleals erste Zeiletext-Blöcke als normale Absätzecontext-Blöcke als kompakte Kontextzeilendivider-Blöcke als visueller Trenner- Button-Labels, einschließlich URLs für Link-Buttons
- Labels von Select-Optionen
Fallback-Sichtbarkeit von Button-Werten
Wenn ein Channel interaktive Controls nicht rendern kann, fallen Button- und Select-Werte auf Klartext zurück. Das Fallback-Verhalten erhält die Nutzbarkeit, während opake Callback-Daten privat bleiben:command-typisierte Aktionen rendern alslabel: \command“, sodass Benutzer den Befehl kopieren und manuell in der Channel-Eingabe ausführen können.callback-typisierte Aktionen und veraltetevalue-Felder rendern nur als Label. Der opake Callback-Wert wird im Fallback-Text nicht offengelegt.url/webApp-Buttons rendern den URL-Text zusammen mit dem Button-Label, da die URL benutzerseitig sichtbar ist.- Select-Optionen rendern nur als Label. Der zugrunde liegende Optionswert wird im Fallback-Text nicht offengelegt.
- Telegram mit deaktivierten Inline-Buttons sendet Text-Fallback.
- Ein Channel ohne Select-Unterstützung listet Select-Optionen als Text auf.
- Ein Nur-URL-Button wird entweder zu einem nativen Link-Button oder zu einer Fallback-URL-Zeile.
- Optionale Pin-Fehler lassen die zugestellte Nachricht nicht fehlschlagen.
delivery.pin.required: true; wenn Pinning als erforderlich angefordert wird und der Channel die gesendete Nachricht nicht pinnen kann, meldet die Zustellung einen Fehler.
Provider-Zuordnung
Aktuelle gebündelte Renderer:| Kanal | Natives Render-Ziel | Hinweise |
|---|---|---|
| Discord | Komponenten und Komponentencontainer | Bewahrt das Legacy-channelData.discord.components für vorhandene provider-native Payload-Produzenten, aber neue gemeinsam genutzte Sends sollten presentation verwenden. |
| Slack | Block Kit | Bewahrt Legacy-channelData.slack.blocks für vorhandene provider-native Payload-Produzenten, aber neue gemeinsam genutzte Sends sollten presentation verwenden. |
| Telegram | Text plus Inline-Tastaturen | Buttons/Selects erfordern Inline-Button-Fähigkeit für die Zieloberfläche; andernfalls wird Text-Fallback verwendet. |
| Mattermost | Text plus interaktive Props | Andere Blöcke werden auf Text reduziert. |
| Microsoft Teams | Adaptive Cards | Einfacher message-Text wird zusammen mit der Karte eingeschlossen, wenn beides bereitgestellt wird. |
| Feishu | Interaktive Karten | Der Kartenkopf kann title verwenden; der Body vermeidet es, diesen Titel zu duplizieren. |
| Einfache Kanäle | Text-Fallback | Kanäle ohne Renderer erhalten trotzdem lesbare Ausgabe. |
Presentation vs InteractiveReply
InteractiveReply ist die ältere interne Teilmenge, die von Genehmigungs- und Interaktions-
Hilfsfunktionen verwendet wird. Sie unterstützt:
- Text
- Buttons
- Selects
MessagePresentation ist der kanonische gemeinsam genutzte Send-Vertrag. Er ergänzt:
- Titel
- Ton
- Kontext
- Trenner
- reine URL-Buttons
- generische Zustellungsmetadaten über
ReplyPayload.delivery
openclaw/plugin-sdk/interactive-runtime, wenn Sie älteren
Code überbrücken:
OC_I18N_900011
Neuer Code sollte MessagePresentation direkt akzeptieren oder erzeugen. Vorhandene
interactive-Payloads sind eine veraltete Teilmenge von presentation; Runtime-
Unterstützung bleibt für ältere Produzenten erhalten.
Die Legacy-InteractiveReply*-Typen und Konvertierungshilfen sind im SDK als
@deprecated markiert:
InteractiveReply,InteractiveReplyBlock,InteractiveReplyButton,InteractiveReplyOption,InteractiveReplySelectBlockundInteractiveReplyTextBlocknormalizeInteractiveReply(...)hasInteractiveReplyBlocks(...)interactiveReplyToPresentation(...)presentationToInteractiveReply(...)presentationToInteractiveControlsReply(...)resolveInteractiveTextFallback(...)reduceInteractiveReply(...)
presentationToInteractiveReply(...) und
presentationToInteractiveControlsReply(...) bleiben als Renderer-
Brücken für Legacy-Kanalimplementierungen verfügbar. Neuer Produzenten-Code sollte sie
nicht aufrufen; senden Sie presentation und lassen Sie Core/Kanal-Anpassung das Rendering übernehmen.
Genehmigungshilfen haben ebenfalls presentation-first-Ersatzfunktionen:
- Verwenden Sie
buildApprovalPresentationFromActionDescriptors(...)anstelle vonbuildApprovalInteractiveReplyFromActionDescriptors(...) - Verwenden Sie
buildApprovalPresentation(...)anstelle vonbuildApprovalInteractiveReply(...) - Verwenden Sie
buildExecApprovalPresentation(...)anstelle vonbuildExecApprovalInteractiveReply(...)
renderMessagePresentationFallbackText(...) gibt für
Presentation-Blöcke ohne Text-Fallback eine leere Zeichenkette zurück, etwa bei einer nur aus einem Trenner bestehenden
Presentation. Transports, die einen nicht leeren Send-Body erfordern, können
emptyFallback übergeben, um einen minimalen Body zu verwenden, ohne den Standard-Fallback-
Vertrag zu ändern.
Zustellungs-Pin
Anheften ist Zustellungsverhalten, nicht Presentation. Verwenden Siedelivery.pin anstelle
provider-nativer Felder wie channelData.telegram.pin.
Semantik:
pin: trueheftet die erste erfolgreich zugestellte Nachricht an.pin.notifyist standardmäßigfalse.pin.requiredist standardmäßigfalse.- Optionale Pin-Fehler werden reduziert und lassen die gesendete Nachricht intakt.
- Erforderliche Pin-Fehler lassen die Zustellung fehlschlagen.
- Aufgeteilte Nachrichten heften den ersten zugestellten Abschnitt an, nicht den letzten Abschnitt.
pin, unpin und pins existieren weiterhin für vorhandene
Nachrichten, bei denen der Provider diese Vorgänge unterstützt.
Checkliste für Plugin-Autoren
- Deklarieren Sie
presentationausdescribeMessageTool(...), wenn der Kanal semantische Presentation rendern oder sicher reduzieren kann. - Fügen Sie
presentationCapabilitieszum Runtime-Outbound-Adapter hinzu. - Implementieren Sie
renderPresentationim Runtime-Code, nicht im Control-Plane-Plugin- Setup-Code. - Halten Sie native UI-Bibliotheken aus heißen Setup-/Katalogpfaden heraus.
- Deklarieren Sie generische Fähigkeitslimits unter
presentationCapabilities.limits, wenn sie bekannt sind. - Bewahren Sie endgültige Plattformlimits im Renderer und in Tests.
- Fügen Sie Fallback-Tests für nicht unterstützte Buttons, Selects, URL-Buttons, Titel/Text-
Duplizierung und gemischte Sends aus
messagepluspresentationhinzu. - Fügen Sie Unterstützung für Zustellungs-Pins über
deliveryCapabilities.pinundpinDeliveredMessagenur hinzu, wenn der Provider die gesendete Nachrichten-ID anheften kann. - Legen Sie keine neuen provider-nativen Karten-/Block-/Komponenten-/Button-Felder über das gemeinsam genutzte Nachrichtenaktionsschema offen.