Get started
Refactorplan voor kanaalpresentatie
Status
Geïmplementeerd voor de gedeelde agent-, CLI-, Plugin-capaciteits- en uitgaande afleveringsoppervlakken:
ReplyPayload.presentationbevat semantische bericht-UI.ReplyPayload.delivery.pinbevat verzoeken om verzonden berichten vast te pinnen.- Gedeelde berichtacties stellen
presentation,deliveryenpinbeschikbaar in plaats van providerspecifiekecomponents,blocks,buttonsofcard. - De kern rendert de presentatie of degradeert deze automatisch via door Plugins gedeclareerde uitgaande capaciteiten.
- Renderers voor Discord, Slack, Telegram, Mattermost, MS Teams en Feishu gebruiken het generieke contract.
- De besturingsvlakcode van het Discord-kanaal importeert niet langer door Carbon ondersteunde UI-containers.
De canonieke documentatie staat nu in Berichtpresentatie. Bewaar dit plan als historische implementatiecontext; werk de canonieke handleiding bij voor wijzigingen in het contract, de renderer of het terugvalgedrag.
Probleem
De kanaal-UI is momenteel verdeeld over meerdere incompatibele oppervlakken:
- De kern beheert via
buildCrossContextComponentseen op Discord gebaseerde renderer-hook voor meerdere contexten. - Discord
channel.tskan viaDiscordUiContainerde systeemeigen Carbon-UI importeren, waardoor UI-runtimeafhankelijkheden in het besturingsvlak van de kanaal-Plugin terechtkomen. - De agent en CLI bieden providerspecifieke uitwegen voor systeemeigen payloads, zoals Discord
components, Slackblocks, Telegram- of Mattermost-buttonsen Teams- of Feishu-card. ReplyPayload.channelDatabevat zowel transportaanwijzingen als systeemeigen UI-enveloppen.- Het generieke
interactive-model bestaat, maar is beperkter dan de rijkere indelingen die Discord, Slack, Teams, Feishu, LINE, Telegram en Mattermost al gebruiken.
Hierdoor is de kern op de hoogte van systeemeigen UI-structuren, wordt het uitgesteld laden van de Plugin-runtime verzwakt en krijgen agents te veel providerspecifieke manieren om dezelfde berichtintentie uit te drukken.
Doelen
- De kern bepaalt op basis van gedeclareerde capaciteiten de beste semantische presentatie voor een bericht.
- Extensies declareren capaciteiten en renderen semantische presentatie naar systeemeigen transportpayloads.
- De Web Control UI blijft gescheiden van de systeemeigen chat-UI.
- Systeemeigen kanaalpayloads worden niet beschikbaar gesteld via het gedeelde berichtoppervlak van de agent of CLI.
- Niet-ondersteunde presentatiefuncties degraderen automatisch naar de beste tekstweergave.
- Afleveringsgedrag, zoals het vastpinnen van een verzonden bericht, is generieke afleveringsmetadata en geen presentatie.
Geen doelen
- Geen achterwaartse-compatibiliteitsshim voor
buildCrossContextComponents. - Geen openbare systeemeigen uitwegen voor
components,blocks,buttonsofcard. - Geen imports van kanaalspecifieke UI-bibliotheken in de kern.
- Geen providerspecifieke SDK-koppelvlakken voor gebundelde kanalen.
Doelmodel
Voeg een door de kern beheerd veld presentation toe aan ReplyPayload.
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;};Tijdens de migratie wordt interactive een subset van presentation:
- Het tekstblok van
interactivewordt toegewezen aanpresentation.blocks[].type = "text". - Het knoppenblok van
interactivewordt toegewezen aanpresentation.blocks[].type = "buttons". - Het selectieblok van
interactivewordt toegewezen aanpresentation.blocks[].type = "select".
De externe schema's voor agent en CLI gebruiken nu presentation; interactive blijft een interne verouderde parser-/rendererhelper voor bestaande antwoordproducenten.
De openbare producentgerichte API beschouwt interactive als verouderd. Runtime-
ondersteuning blijft bestaan, zodat bestaande goedkeuringshelpers en oudere Plugins blijven
werken terwijl nieuwe code presentation uitvoert.
Afleveringsmetadata
Voeg een door de kern beheerd veld delivery toe voor verzendgedrag dat geen UI is.
type ReplyPayloadDelivery = { pin?: | boolean | { enabled: boolean; notify?: boolean; required?: boolean; };};Semantiek:
delivery.pin = truebetekent dat het eerste succesvol afgeleverde bericht wordt vastgepind.notifyis standaardfalse.requiredis standaardfalse; niet-ondersteunde kanalen of mislukt vastpinnen degraderen automatisch door de aflevering voort te zetten.- Handmatige berichtacties
pin,unpinenlist-pinsblijven beschikbaar voor bestaande berichten.
De huidige koppeling van Telegram ACP-onderwerpen moet worden verplaatst van channelData.telegram.pin = true naar delivery.pin = true.
Runtimecapaciteitscontract
Voeg hooks voor het renderen van presentatie en aflevering toe aan de uitgaande runtimeadapter, niet aan de kanaal-Plugin van het besturingsvlak.
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>;};Kerngedrag:
- Bepaal het doelkanaal en de runtimeadapter.
- Vraag de presentatiecapaciteiten op.
- Degradeer niet-ondersteunde blokken en pas generieke capaciteitslimieten toe vóór het renderen.
- Roep
renderPresentationaan. - Als er geen renderer bestaat, zet de presentatie om naar tekst als terugvaloptie.
- Roep na succesvolle verzending
pinDeliveredMessageaan wanneerdelivery.pinis aangevraagd en wordt ondersteund.
Kanaaltoewijzing
Discord:
- Render
presentationnaar componenten v2 en Carbon-containers in modules die uitsluitend tijdens runtime worden gebruikt. - Bewaar helpers voor accentkleuren in lichte modules.
- Verwijder imports van
DiscordUiContaineruit de besturingsvlakcode van de kanaal-Plugin.
Slack:
- Render
presentationnaar Block Kit. - Verwijder
blocks-invoer voor agent en CLI.
Telegram:
- Render tekst, context en scheidingslijnen als tekst.
- Render acties en selecties als inline-toetsenborden wanneer deze zijn geconfigureerd en toegestaan voor het doeloppervlak.
- Gebruik tekst als terugvaloptie wanneer inlineknoppen zijn uitgeschakeld.
- Verplaats het vastpinnen van ACP-onderwerpen naar
delivery.pin.
Mattermost:
- Render acties als interactieve knoppen wanneer deze zijn geconfigureerd.
- Render andere blokken als tekstterugval.
MS Teams:
- Render
presentationnaar Adaptive Cards. - Behoud handmatige acties voor vastpinnen, losmaken en het weergeven van vastgepinde berichten.
- Implementeer eventueel
pinDeliveredMessageals Graph-ondersteuning betrouwbaar is voor het doelgesprek.
Feishu:
- Render
presentationnaar interactieve kaarten. - Behoud handmatige acties voor vastpinnen, losmaken en het weergeven van vastgepinde berichten.
- Implementeer eventueel
pinDeliveredMessagevoor het vastpinnen van verzonden berichten als het API-gedrag betrouwbaar is.
LINE:
- Render
presentationwaar mogelijk naar Flex- of sjabloonberichten. - Val voor niet-ondersteunde blokken terug op tekst.
- Verwijder LINE-UI-payloads uit
channelData.
Eenvoudige of beperkte kanalen:
- Zet de presentatie met conservatieve opmaak om naar tekst.
Refactorstappen
- Pas de Discord-releasefix opnieuw toe die
ui-colors.tsafsplitst van de door Carbon ondersteunde UI enDiscordUiContainerverwijdert uitextensions/discord/src/channel.ts. - Voeg
presentationendeliverytoe aanReplyPayload, normalisatie van uitgaande payloads, afleveringsoverzichten en hook-payloads. - Voeg het schema
MessagePresentationen parserhelpers toe in een beperkt SDK-/runtime-subpad. - Vervang berichtcapaciteiten
buttons,cards,componentsenblocksdoor semantische presentatiecapaciteiten. - Voeg hooks voor presentatierendering en vastpinnen bij aflevering toe aan de uitgaande runtimeadapter.
- Vervang de constructie van componenten voor meerdere contexten door
buildCrossContextPresentation. - Verwijder
src/infra/outbound/channel-adapters.tsen verwijderbuildCrossContextComponentsuit de typen van de kanaal-Plugin. - Wijzig
maybeApplyCrossContextMarkerzodat dezepresentationtoevoegt in plaats van systeemeigen parameters. - Werk verzendpaden voor Plugin-dispatch bij zodat ze uitsluitend semantische presentatie en afleveringsmetadata gebruiken.
- Verwijder systeemeigen payloadparameters voor agent en CLI:
components,blocks,buttonsencard. - Verwijder SDK-helpers die systeemeigen schema's voor berichttools maken en vervang ze door helpers voor presentatieschema's.
- Verwijder UI-/systeemeigen enveloppen uit
channelData; behoud alleen transportmetadata totdat elk resterend veld is beoordeeld. - Migreer de renderers voor Discord, Slack, Telegram, Mattermost, MS Teams, Feishu en LINE.
- Werk de documentatie bij voor de berichten-CLI, kanaalpagina's, Plugin-SDK en de capaciteitencookbook.
- Voer import-fan-outprofilering uit voor Discord en de betrokken kanaalingangspunten.
Stappen 1-11 en 13-14 zijn in deze refactor geïmplementeerd voor de gedeelde agent-, CLI-, Plugin-capaciteits- en uitgaande-adaptercontracten. Stap 12 blijft een grondigere interne opschoningsronde voor providerprivate channelData-transportenveloppen. Stap 15 blijft een vervolgvalidatie als we gekwantificeerde import-fan-outcijfers willen naast de type-/testcontrole.
Tests
Toevoegen of bijwerken:
- Tests voor presentatienormalisatie.
- Tests voor automatische degradatie van presentaties bij niet-ondersteunde blokken.
- Tests voor markeringen tussen contexten voor Plugin-dispatch en kernafleveringspaden.
- Matrixtests voor kanaalrendering voor Discord, Slack, Telegram, Mattermost, MS Teams, Feishu, LINE en tekstterugval.
- Tests voor berichttoolschema's die aantonen dat systeemeigen velden zijn verwijderd.
- CLI-tests die aantonen dat systeemeigen vlaggen zijn verwijderd.
- Regressietest voor uitgesteld importeren bij het Discord-ingangspunt met betrekking tot Carbon.
- Tests voor vastpinnen bij aflevering voor Telegram en generieke terugval.
Open vragen
- Moet
delivery.pinin de eerste ronde worden geïmplementeerd voor Discord, Slack, MS Teams en Feishu, of eerst alleen voor Telegram? - Moet
deliveryuiteindelijk bestaande velden zoalsreplyToId,replyToCurrent,silentenaudioAsVoiceopnemen, of gericht blijven op gedrag na verzending? - Moet presentatie rechtstreeks afbeeldingen of bestandsverwijzingen ondersteunen, of moeten media voorlopig gescheiden blijven van de UI-indeling?