Status
Implementiert für die Oberflächen des gemeinsamen Agenten, der CLI, der Plugin-Fähigkeiten und der ausgehenden Zustellung:ReplyPayload.presentationträgt semantische Nachrichten-UI.ReplyPayload.delivery.pinträgt Pin-Anfragen für gesendete Nachrichten.- Gemeinsame Nachrichtenaktionen stellen
presentation,deliveryundpinstatt providernativercomponents,blocks,buttonsodercardbereit. - Der Core rendert oder degradiert die Darstellung automatisch über vom Plugin deklarierte ausgehende Fähigkeiten.
- Renderer für Discord, Slack, Telegram, Mattermost, MS Teams und Feishu nutzen den generischen Vertrag.
- Der Discord-Control-Plane-Code des Kanals importiert keine Carbon-gestützten UI-Container mehr.
Problem
Die Kanal-UI ist derzeit über mehrere inkompatible Oberflächen aufgeteilt:- Der Core besitzt einen Discord-geprägten Renderer-Hook für kontextübergreifende Nutzung über
buildCrossContextComponents. - Discord
channel.tskann native Carbon-UI überDiscordUiContainerimportieren, was Laufzeit-UI-Abhängigkeiten in die Control Plane des Kanal-Plugins zieht. - Der Agent und die CLI stellen native Payload-Escape-Hatches wie Discord-
components, Slack-blocks, Telegram- oder Mattermost-buttonssowie Teams- oder Feishu-cardbereit. ReplyPayload.channelDataträgt sowohl Transporthinweise als auch native UI-Hüllen.- Das generische
interactive-Modell existiert, ist aber schmaler als die reicheren Layouts, die bereits von Discord, Slack, Teams, Feishu, LINE, Telegram und Mattermost verwendet werden.
Ziele
- Der Core entscheidet anhand deklarierter Fähigkeiten über die beste semantische Darstellung für eine Nachricht.
- Extensions deklarieren Fähigkeiten und rendern semantische Darstellung in native Transport-Payloads.
- Die Web Control UI bleibt von nativer Chat-UI getrennt.
- Native Kanal-Payloads werden nicht über die gemeinsame Oberfläche von Agent oder CLI bereitgestellt.
- Nicht unterstützte Darstellungsmerkmale degradieren automatisch zur besten Textdarstellung.
- Zustellverhalten wie das Anheften einer gesendeten Nachricht ist generische Zustellmetadaten, keine Darstellung.
Keine Ziele
- Kein Abwärtskompatibilitäts-Shim für
buildCrossContextComponents. - Keine öffentlichen nativen Escape-Hatches für
components,blocks,buttonsodercard. - Keine Core-Importe von kanalnativen UI-Bibliotheken.
- Keine providerspezifischen SDK-Seams für gebündelte Kanäle.
Zielmodell
Fügen Sie ein Core-eigenes Feldpresentation zu ReplyPayload hinzu.
interactive wird während der Migration zu einer Teilmenge von presentation:
- Ein
interactive-Textblock wird aufpresentation.blocks[].type = "text"abgebildet. - Ein
interactive-Buttons-Block wird aufpresentation.blocks[].type = "buttons"abgebildet. - Ein
interactive-Select-Block wird aufpresentation.blocks[].type = "select"abgebildet.
presentation; interactive bleibt ein interner Legacy-Parser-/Rendering-Helfer für bestehende Reply-Erzeuger.
Zustellmetadaten
Fügen Sie ein Core-eigenes Felddelivery für Sendeverhalten hinzu, das keine UI ist.
delivery.pin = truebedeutet, die erste erfolgreich zugestellte Nachricht anzuheften.notifyist standardmäßigfalse.requiredist standardmäßigfalse; nicht unterstützte Kanäle oder fehlgeschlagenes Pinning degradieren automatisch, indem die Zustellung fortgesetzt wird.- Manuelle Nachrichtenaktionen
pin,unpinundlist-pinsbleiben für bestehende Nachrichten erhalten.
channelData.telegram.pin = true auf delivery.pin = true verschoben werden.
Vertrag für Laufzeit-Fähigkeiten
Fügen Sie Hooks für Darstellung und Zustell-Rendering zum ausgehenden Laufzeit-Adapter hinzu, nicht zum Kanal-Plugin der Control Plane.- Zielkanal und Laufzeit-Adapter auflösen.
- Nach Darstellungsfähigkeiten fragen.
- Nicht unterstützte Blöcke vor dem Rendering degradieren.
renderPresentationaufrufen.- Wenn kein Renderer existiert, Darstellung in einen Text-Fallback umwandeln.
- Nach erfolgreichem Senden
pinDeliveredMessageaufrufen, wenndelivery.pinangefordert und unterstützt wird.
Kanalzuordnung
Discord:presentationin Components v2 und Carbon-Container in Modulen nur für die Laufzeit rendern.- Helfer für Akzentfarben in leichten Modulen behalten.
DiscordUiContainer-Importe aus dem Control-Plane-Code des Kanal-Plugins entfernen.
presentationin Block Kit rendern.blocks-Eingabe aus Agent und CLI entfernen.
- Text, Kontext und Divider als Text rendern.
- Aktionen und Select als Inline-Keyboards rendern, wenn sie konfiguriert und für die Zieloberfläche erlaubt sind.
- Text-Fallback verwenden, wenn Inline-Buttons deaktiviert sind.
- ACP-Themen-Pinning zu
delivery.pinverschieben.
- Aktionen, wo konfiguriert, als interaktive Buttons rendern.
- Andere Blöcke als Text-Fallback rendern.
presentationin Adaptive Cards rendern.- Manuelle Aktionen
pin/unpin/list-pinsbeibehalten. - Optional
pinDeliveredMessageimplementieren, wenn Graph-Unterstützung für die Zielkonversation zuverlässig ist.
presentationin interaktive Karten rendern.- Manuelle Aktionen
pin/unpin/list-pinsbeibehalten. - Optional
pinDeliveredMessagefür Pinning gesendeter Nachrichten implementieren, wenn das API-Verhalten zuverlässig ist.
presentation, wo möglich, in Flex- oder Template-Nachrichten rendern.- Für nicht unterstützte Blöcke auf Text zurückfallen.
- LINE-UI-Payloads aus
channelDataentfernen.
- Darstellung mit konservativer Formatierung in Text umwandeln.
Refactoring-Schritte
- Den Discord-Release-Fix erneut anwenden, der
ui-colors.tsvon Carbon-gestützter UI trennt undDiscordUiContainerausextensions/discord/src/channel.tsentfernt. presentationunddeliveryzuReplyPayload, Normalisierung ausgehender Payloads, Zustellzusammenfassungen und Hook-Payloads hinzufügen.- Schema und Parser-Helfer für
MessagePresentationin einem schmalen SDK-/Laufzeit-Unterpfad hinzufügen. - Nachrichtenfähigkeiten
buttons,cards,componentsundblocksdurch semantische Darstellungsfähigkeiten ersetzen. - Hooks im ausgehenden Laufzeit-Adapter für Darstellungs-Rendering und Zustell-Pinning hinzufügen.
- Konstruktion kontextübergreifender Komponenten durch
buildCrossContextPresentationersetzen. src/infra/outbound/channel-adapters.tslöschen undbuildCrossContextComponentsaus den Typen für Kanal-Plugins entfernen.maybeApplyCrossContextMarkerso ändern, dasspresentationstatt nativer Parameter angehängt wird.- Plugin-Dispatch-Sendepfade aktualisieren, damit sie nur semantische Darstellung und Zustellmetadaten nutzen.
- Native Payload-Parameter aus Agent und CLI entfernen:
components,blocks,buttonsundcard. - SDK-Helfer entfernen, die native Nachrichtentool-Schemata erzeugen, und durch Helfer für Darstellungsschemata ersetzen.
- UI-/native Hüllen aus
channelDataentfernen; bis jedes verbleibende Feld geprüft wurde, nur Transportmetadaten behalten. - Renderer für Discord, Slack, Telegram, Mattermost, MS Teams, Feishu und LINE migrieren.
- Dokumentation für Message-CLI, Kanalseiten, Plugin-SDK und Capability-Cookbook aktualisieren.
- Import-Fanout-Profiling für Discord und betroffene Kanal-Entry-Points ausführen.
channelData-Transporthüllen. Schritt 15 bleibt eine nachgelagerte Validierung, falls wir quantifizierte Import-Fanout-Zahlen jenseits des Typ-/Test-Gates möchten.
Tests
Hinzufügen oder aktualisieren:- Tests zur Darstellungsnormalisierung.
- Tests zur automatischen Degradierung der Darstellung bei nicht unterstützten Blöcken.
- Tests für kontextübergreifende Marker bei Plugin-Dispatch und Core-Zustellpfaden.
- Kanal-Render-Matrix-Tests für Discord, Slack, Telegram, Mattermost, MS Teams, Feishu, LINE und Text-Fallback.
- Tests für Nachrichtentool-Schemata, die belegen, dass native Felder entfernt wurden.
- CLI-Tests, die belegen, dass native Flags entfernt wurden.
- Regression zur Import-Lazy-Loading-Eigenschaft des Discord-Entry-Points in Bezug auf Carbon.
- Delivery-Pin-Tests für Telegram und generischen Fallback.
Offene Fragen
- Sollte
delivery.pinim ersten Durchgang für Discord, Slack, MS Teams und Feishu implementiert werden, oder zunächst nur für Telegram? - Sollte
deliveryletztlich bestehende Felder wiereplyToId,replyToCurrent,silentundaudioAsVoiceaufnehmen oder auf Verhalten nach dem Senden fokussiert bleiben? - Sollte die Darstellung direkt Bilder oder Dateireferenzen unterstützen, oder sollten Medien vorerst von der UI-Layoutlogik getrennt bleiben?