A apresentação de mensagens é o contrato compartilhado da OpenClaw para UI de chat de saída avançada. Ela permite que agentes, comandos da CLI, fluxos de aprovação e plugins descrevam a intenção da mensagem uma vez, enquanto cada plugin de canal renderiza a melhor forma nativa possível. Use apresentação para UI de mensagens portátil:Documentation Index
Fetch the complete documentation index at: https://docs2.openclaw.ai/llms.txt
Use this file to discover all available pages before exploring further.
- seções de texto
- texto pequeno de contexto/rodapé
- divisores
- botões
- menus de seleção
- título e tom de cartão
components do Discord, blocks
do Slack, buttons do Telegram, card do Teams ou card do Feishu à ferramenta
de mensagem compartilhada. Eles são saídas de renderização pertencentes ao plugin de canal.
Contrato
Autores de Plugin importam o contrato público de:valueé um valor de ação da aplicação roteado de volta pelo caminho de interação existente do canal quando o canal oferece suporte a controles clicáveis.urlé um botão de link. Ele pode existir semvalue.labelé obrigatório e também é usado no fallback de texto.styleé consultivo. Renderizadores devem mapear estilos não compatíveis para um padrão seguro, não falhar o envio.
options[].valueé o valor da aplicação selecionado.placeholderé consultivo e pode ser ignorado por canais sem suporte nativo a seleção.- Se um canal não oferecer suporte a seleções, o texto de fallback lista os rótulos.
Exemplos de produtores
Cartão simples:Contrato do renderizador
Plugins de canal declaram suporte de renderização em seu adaptador de saída:Fluxo de renderização do núcleo
Quando umReplyPayload ou ação de mensagem inclui presentation, o núcleo:
- Normaliza o payload de apresentação.
- Resolve o adaptador de saída do canal de destino.
- Lê
presentationCapabilities. - Chama
renderPresentationquando o adaptador consegue renderizar o payload. - Usa fallback para texto conservador quando o adaptador está ausente ou não consegue renderizar.
- Envia o payload resultante pelo caminho normal de entrega do canal.
- Aplica metadados de entrega, como
delivery.pin, após a primeira mensagem enviada com sucesso.
Regras de degradação
A apresentação deve ser segura para envio em canais limitados. O texto de fallback inclui:titlecomo a primeira linha- blocos
textcomo parágrafos normais - blocos
contextcomo linhas compactas de contexto - blocos
dividercomo separador visual - rótulos de botões, incluindo URLs para botões de link
- rótulos de opções de seleção
- Telegram com botões inline desativados envia fallback de texto.
- Um canal sem suporte a seleção lista as opções de seleção como texto.
- Um botão apenas com URL se torna um botão de link nativo ou uma linha de URL de fallback.
- Falhas opcionais de fixação não fazem a mensagem entregue falhar.
delivery.pin.required: true; se a fixação for solicitada como
obrigatória e o canal não puder fixar a mensagem enviada, a entrega informa falha.
Mapeamento de provedores
Renderizadores incluídos atualmente:| Canal | Destino de renderização nativa | Observações |
|---|---|---|
| Discord | Componentes e contêineres de componentes | Preserva channelData.discord.components legado para produtores de payload nativo de provedor existentes, mas novos envios compartilhados devem usar presentation. |
| Slack | Block Kit | Preserva channelData.slack.blocks legado para produtores de payload nativo de provedor existentes, mas novos envios compartilhados devem usar presentation. |
| Telegram | Texto mais teclados inline | Botões/seleções exigem capacidade de botão inline para a superfície de destino; caso contrário, fallback de texto é usado. |
| Mattermost | Texto mais props interativas | Outros blocos degradam para texto. |
| Microsoft Teams | Adaptive Cards | O texto simples de message é incluído com o cartão quando ambos são fornecidos. |
| Feishu | Cartões interativos | O cabeçalho do cartão pode usar title; o corpo evita duplicar esse título. |
| Canais simples | Fallback de texto | Canais sem renderizador ainda recebem uma saída legível. |
Apresentação vs InteractiveReply
InteractiveReply é o subconjunto interno mais antigo usado por auxiliares de aprovação e interação.
Ele oferece suporte a:
- texto
- botões
- seleções
MessagePresentation é o contrato canônico de envio compartilhado. Ele adiciona:
- título
- tom
- contexto
- divisor
- botões apenas com URL
- metadados genéricos de entrega por meio de
ReplyPayload.delivery
openclaw/plugin-sdk/interactive-runtime ao fazer a ponte com código
mais antigo:
MessagePresentation diretamente.
presentationToInteractiveReply(...) preserva o texto visível da apresentação ao
mapear o título, texto, contexto, botões e seleções para o formato antigo de
InteractiveReply. Renderizadores de componentes que já desenham título, texto,
contexto e blocos divisores nativamente devem usar
presentationToInteractiveControlsReply(...) em vez disso, e então anexar apenas os
controles de botão e seleção.
renderMessagePresentationFallbackText(...) retorna uma string vazia para
blocos de apresentação que não têm fallback de texto, como uma apresentação
composta apenas por divisor. Transportes que exigem um corpo de envio não vazio podem passar
emptyFallback para optar por um corpo mínimo sem alterar o contrato de fallback
padrão.
Fixação de entrega
Fixação é comportamento de entrega, não apresentação. Usedelivery.pin em vez de
campos nativos de provedor, como channelData.telegram.pin.
Semântica:
pin: truefixa a primeira mensagem entregue com sucesso.pin.notifytem como padrãofalse.pin.requiredtem como padrãofalse.- Falhas opcionais de fixação degradam e deixam a mensagem enviada intacta.
- Falhas de fixação obrigatória falham a entrega.
- Mensagens em partes fixam a primeira parte entregue, não a parte final.
pin, unpin e pins ainda existem para mensagens
existentes quando o provedor oferece suporte a essas operações.
Lista de verificação para autores de Plugin
- Declare
presentationa partir dedescribeMessageTool(...)quando o canal puder renderizar ou degradar com segurança a apresentação semântica. - Adicione
presentationCapabilitiesao adaptador de saída em runtime. - Implemente
renderPresentationno código de runtime, não no código de configuração do Plugin de plano de controle. - Mantenha bibliotecas de UI nativa fora dos caminhos quentes de configuração/catálogo.
- Preserve limites da plataforma no renderizador e nos testes.
- Adicione testes de fallback para botões sem suporte, seleções, botões de URL, duplicação
de título/texto e envios mistos de
messagemaispresentation. - Adicione suporte a fixação de entrega por meio de
deliveryCapabilities.pinepinDeliveredMessagesomente quando o provedor puder fixar o id da mensagem enviada. - Não exponha novos campos nativos de provedor de cartão/bloco/componente/botão pelo esquema de ação de mensagem compartilhado.