Get started
Plan zur Überarbeitung der Kanaldarstellung
Status
Implementiert für den gemeinsamen Agenten, die CLI, Plugin-Fähigkeiten und ausgehende Zustellungsoberflächen:
ReplyPayload.presentationüberträgt die semantische Nachrichten-UI.ReplyPayload.delivery.pinüberträgt Anfragen zum Anheften gesendeter Nachrichten.- Gemeinsame Nachrichtenaktionen stellen
presentation,deliveryundpinstatt Provider-nativercomponents,blocks,buttonsodercardbereit. - Der Kern rendert die Darstellung anhand der vom Plugin deklarierten ausgehenden Fähigkeiten oder stuft sie automatisch herab.
- Die Renderer für Discord, Slack, Telegram, Mattermost, MS Teams und Feishu verwenden den generischen Vertrag.
- Der Discord-Control-Plane-Code des Kanals importiert keine Carbon-basierten UI-Container mehr.
Die kanonische Dokumentation befindet sich jetzt unter Nachrichtendarstellung. Bewahren Sie diesen Plan als historischen Implementierungskontext auf; aktualisieren Sie den kanonischen Leitfaden bei Änderungen am Vertrag, Renderer oder Fallback-Verhalten.
Problem
Die Kanal-UI ist derzeit auf mehrere inkompatible Oberflächen verteilt:
- Der Kern besitzt über
buildCrossContextComponentseinen Discord-geprägten, kontextübergreifenden Renderer-Hook. - Discord
channel.tskann überDiscordUiContainereine native Carbon-UI importieren, wodurch UI-Laufzeitabhängigkeiten in die Control Plane des Kanal-Plugins gelangen. - Der Agent und die CLI stellen Schlupflöcher für native Payloads bereit, etwa Discord
components, Slackblocks, Telegram oder Mattermostbuttonssowie Teams oder Feishucard. ReplyPayload.channelDataüberträgt sowohl Transporthinweise als auch native UI-Envelopes.- Das generische Modell
interactiveist vorhanden, aber weniger umfassend als die bereits von Discord, Slack, Teams, Feishu, LINE, Telegram und Mattermost verwendeten umfangreicheren Layouts.
Dadurch kennt der Kern native UI-Strukturen, die verzögerte Plugin-Laufzeitinitialisierung wird geschwächt und Agenten erhalten zu viele Provider-spezifische Möglichkeiten, dieselbe Nachrichtenabsicht auszudrücken.
Ziele
- Der Kern bestimmt anhand deklarierter Fähigkeiten die beste semantische Darstellung für eine Nachricht.
- Erweiterungen deklarieren Fähigkeiten und rendern semantische Darstellungen in native Transport-Payloads.
- Die Web Control UI bleibt von der nativen Chat-UI getrennt.
- Native Kanal-Payloads werden nicht über die gemeinsame Nachrichtenoberfläche des Agenten oder der CLI bereitgestellt.
- Nicht unterstützte Darstellungsfunktionen werden automatisch auf die bestmögliche Textdarstellung herabgestuft.
- Zustellungsverhalten wie das Anheften einer gesendeten Nachricht sind generische Zustellungsmetadaten und keine Darstellung.
Nichtziele
- Kein Abwärtskompatibilitäts-Shim für
buildCrossContextComponents. - Keine öffentlichen nativen Schlupflöcher für
components,blocks,buttonsodercard. - Keine Kernimporte von kanalnativen UI-Bibliotheken.
- Keine Provider-spezifischen SDK-Schnittstellen für gebündelte Kanäle.
Zielmodell
Fügen Sie ReplyPayload ein kerneigenes Feld presentation hinzu.
type MessagePresentationTone = "neutral" | "info" | "success" | "warning" | "danger"; type MessagePresentation = { tone?: MessagePresentationTone; title?: string; blocks: MessagePresentationBlock[];}; type MessagePresentationBlock = | { type: "text"; text: string } | { type: "context"; text: string } | { type: "divider" } | { type: "buttons"; buttons: MessagePresentationButton[] } | { type: "select"; placeholder?: string; options: MessagePresentationOption[] }; type MessagePresentationButton = { label: string; value?: string; url?: string; style?: "primary" | "secondary" | "success" | "danger";}; type MessagePresentationOption = { label: string; value: string;};interactive wird während der Migration zu einer Teilmenge von presentation:
- Der Textblock
interactivewird aufpresentation.blocks[].type = "text"abgebildet. - Der Schaltflächenblock
interactivewird aufpresentation.blocks[].type = "buttons"abgebildet. - Der Auswahlblock
interactivewird aufpresentation.blocks[].type = "select"abgebildet.
Die externen Agenten- und CLI-Schemas verwenden jetzt presentation; interactive bleibt ein interner Legacy-Helfer zum Parsen und Rendern für bestehende Antwortproduzenten.
Die öffentliche API für Produzenten behandelt interactive als veraltet. Die Laufzeitunterstützung
bleibt erhalten, damit bestehende Genehmigungshelfer und ältere Plugins weiterhin
funktionieren, während neuer Code presentation ausgibt.
Zustellungsmetadaten
Fügen Sie für Sendeverhalten, das nicht zur UI gehört, ein kerneigenes Feld delivery hinzu.
type ReplyPayloadDelivery = { pin?: | boolean | { enabled: boolean; notify?: boolean; required?: boolean; };};Semantik:
delivery.pin = truebedeutet, die erste erfolgreich zugestellte Nachricht anzuheften.notifyhat standardmäßig den Wertfalse.requiredhat standardmäßig den Wertfalse; nicht unterstützte Kanäle oder fehlgeschlagenes Anheften werden durch Fortsetzen der Zustellung automatisch herabgestuft.- Manuelle Nachrichtenaktionen
pin,unpinundlist-pinsbleiben für bestehende Nachrichten erhalten.
Die aktuelle Bindung von Telegram-ACP-Themen sollte von channelData.telegram.pin = true nach delivery.pin = true verschoben werden.
Vertrag für Laufzeitfähigkeiten
Fügen Sie dem ausgehenden Laufzeitadapter Hooks für Darstellung und Zustellung hinzu, nicht dem Control-Plane-Kanal-Plugin.
type ChannelPresentationCapabilities = { supported: boolean; buttons?: boolean; selects?: boolean; context?: boolean; divider?: boolean; tones?: MessagePresentationTone[]; limits?: { actions?: { maxActions?: number; maxActionsPerRow?: number; maxRows?: number; maxLabelLength?: number; maxValueBytes?: number; supportsStyles?: boolean; supportsDisabled?: boolean; supportsLayoutHints?: boolean; }; selects?: { maxOptions?: number; maxLabelLength?: number; maxValueBytes?: number; }; text?: { maxLength?: number; encoding?: "characters" | "utf8-bytes" | "utf16-units"; markdownDialect?: "plain" | "markdown" | "html" | "slack-mrkdwn" | "discord-markdown"; supportsEdit?: boolean; }; };}; type ChannelDeliveryCapabilities = { pinSentMessage?: boolean;}; type ChannelOutboundAdapter = { presentationCapabilities?: ChannelPresentationCapabilities; renderPresentation?: (params: { payload: ReplyPayload; presentation: MessagePresentation; ctx: ChannelOutboundSendContext; }) => ReplyPayload | null; deliveryCapabilities?: ChannelDeliveryCapabilities; pinDeliveredMessage?: (params: { cfg: OpenClawConfig; accountId?: string | null; to: string; threadId?: string | number | null; messageId: string; notify: boolean; }) => Promise<void>;};Kernverhalten:
- Zielkanal und Laufzeitadapter auflösen.
- Darstellungsfähigkeiten abfragen.
- Nicht unterstützte Blöcke herabstufen und vor dem Rendern generische Fähigkeitsgrenzen anwenden.
renderPresentationaufrufen.- Wenn kein Renderer vorhanden ist, die Darstellung in einen Text-Fallback konvertieren.
- Nach erfolgreichem Senden
pinDeliveredMessageaufrufen, wenndelivery.pinangefordert wird und unterstützt ist.
Kanalzuordnung
Discord:
presentationin laufzeitexklusiven Modulen als Components v2 und Carbon-Container rendern.- Hilfsfunktionen für Akzentfarben in schlanken Modulen belassen.
DiscordUiContainer-Importe aus dem Control-Plane-Code des Kanal-Plugins entfernen.
Slack:
presentationals Block Kit rendern.- Die Eingabe
blocksaus Agent und CLI entfernen.
Telegram:
- Text, Kontext und Trennlinien als Text rendern.
- Aktionen und Auswahlfelder als Inline-Tastaturen rendern, wenn sie konfiguriert und für die Zieloberfläche zulässig sind.
- Text-Fallback verwenden, wenn Inline-Schaltflächen deaktiviert sind.
- Das Anheften von ACP-Themen nach
delivery.pinverschieben.
Mattermost:
- Aktionen als interaktive Schaltflächen rendern, sofern konfiguriert.
- Andere Blöcke als Text-Fallback rendern.
MS Teams:
presentationals Adaptive Cards rendern.- Manuelle Aktionen zum Anheften, Lösen und Auflisten angehefteter Nachrichten beibehalten.
pinDeliveredMessageoptional implementieren, wenn die Graph-Unterstützung für die Zielkonversation zuverlässig ist.
Feishu:
presentationals interaktive Karten rendern.- Manuelle Aktionen zum Anheften, Lösen und Auflisten angehefteter Nachrichten beibehalten.
pinDeliveredMessageoptional für das Anheften gesendeter Nachrichten implementieren, wenn das API-Verhalten zuverlässig ist.
LINE:
presentationnach Möglichkeit als Flex- oder Vorlagennachrichten rendern.- Bei nicht unterstützten Blöcken auf Text zurückfallen.
- LINE-UI-Payloads aus
channelDataentfernen.
Einfache oder eingeschränkte Kanäle:
- Die Darstellung mit konservativer Formatierung in Text konvertieren.
Refactoring-Schritte
- Den Discord-Release-Fix erneut anwenden, der
ui-colors.tsvon der Carbon-basierten UI trennt undDiscordUiContainerausextensions/discord/src/channel.tsentfernt. presentationunddeliveryzuReplyPayload, der Normalisierung ausgehender Payloads, Zustellungszusammenfassungen und Hook-Payloads hinzufügen.- Das Schema
MessagePresentationund Parser-Hilfsfunktionen in einem eng begrenzten SDK-/Laufzeit-Unterpfad hinzufügen. - Die Nachrichtenfähigkeiten
buttons,cards,componentsundblocksdurch semantische Darstellungsfähigkeiten ersetzen. - Hooks für das Rendern von Darstellungen und das Anheften bei der Zustellung zum ausgehenden Laufzeitadapter hinzufügen.
- Die kontextübergreifende Komponentenerstellung durch
buildCrossContextPresentationersetzen. src/infra/outbound/channel-adapters.tslöschen undbuildCrossContextComponentsaus den Kanal-Plugin-Typen entfernen.maybeApplyCrossContextMarkerso ändern, dasspresentationstatt nativer Parameter angefügt wird.- Die Sendepfade der Plugin-Weiterleitung so aktualisieren, dass sie nur semantische Darstellungs- und Zustellungsmetadaten verarbeiten.
- Native Payload-Parameter aus Agent und CLI entfernen:
components,blocks,buttonsundcard. - SDK-Hilfsfunktionen entfernen, die native Nachrichtenwerkzeug-Schemas erstellen, und sie durch Hilfsfunktionen für Darstellungsschemas ersetzen.
- UI-/native Envelopes aus
channelDataentfernen; nur Transportmetadaten beibehalten, bis jedes verbleibende Feld geprüft wurde. - Die Renderer für Discord, Slack, Telegram, Mattermost, MS Teams, Feishu und LINE migrieren.
- Die Dokumentation für die Nachrichten-CLI, Kanalseiten, das Plugin-SDK und das Fähigkeiten-Cookbook aktualisieren.
- Import-Fan-out-Profiling für Discord und betroffene Kanaleinstiegspunkte ausführen.
Die Schritte 1–11 und 13–14 sind in diesem Refactoring für den gemeinsamen Agenten, die CLI, Plugin-Fähigkeiten und Verträge ausgehender Adapter implementiert. Schritt 12 bleibt ein umfassenderer interner Bereinigungsdurchlauf für Provider-private channelData-Transport-Envelopes. Schritt 15 bleibt eine nachgelagerte Validierung, falls quantifizierte Import-Fan-out-Werte über das Typ-/Test-Gate hinaus gewünscht sind.
Tests
Hinzufügen oder aktualisieren:
- Tests zur Darstellungsnormalisierung.
- Tests zur automatischen Herabstufung der Darstellung bei nicht unterstützten Blöcken.
- Tests für kontextübergreifende Marker bei der Plugin-Weiterleitung und in den Kernzustellungspfaden.
- Tests der Kanal-Renderer-Matrix für Discord, Slack, Telegram, Mattermost, MS Teams, Feishu, LINE und den Text-Fallback.
- Tests des Nachrichtenwerkzeug-Schemas, die nachweisen, dass native Felder entfernt wurden.
- CLI-Tests, die nachweisen, dass native Flags entfernt wurden.
- Regressionstest für die verzögerte Importinitialisierung des Discord-Einstiegspunkts mit Carbon.
- Tests zum Anheften bei der Zustellung für Telegram und den generischen Fallback.
Offene Fragen
- Sollte
delivery.pinim ersten Durchlauf für Discord, Slack, Microsoft Teams und Feishu implementiert werden oder zunächst nur für Telegram? - Sollte
deliveryletztendlich vorhandene Felder wiereplyToId,replyToCurrent,silentundaudioAsVoiceübernehmen oder auf Verhaltensweisen nach dem Senden beschränkt bleiben? - Sollte die Präsentation Bilder oder Dateiverweise direkt unterstützen oder sollten Medien vorerst vom UI-Layout getrennt bleiben?