Status
Implementado para o agente compartilhado, CLI, capacidade de Plugin e superfícies de entrega de saída:ReplyPayload.presentationcarrega interface semântica de mensagem.ReplyPayload.delivery.pincarrega solicitações de fixação de mensagem enviada.- Ações compartilhadas de mensagem expõem
presentation,deliveryepinem vez decomponents,blocks,buttonsoucardnativos do provedor. - O core renderiza ou faz degradação automática da apresentação por meio de capacidades de saída declaradas pelo Plugin.
- Renderizadores de Discord, Slack, Telegram, Mattermost, MS Teams e Feishu consomem o contrato genérico.
- O código do plano de controle de canal do Discord não importa mais contêineres de interface com suporte de Carbon.
Problema
A interface de canal atualmente está dividida em várias superfícies incompatíveis:- O core controla um hook de renderização entre contextos com formato de Discord por meio de
buildCrossContextComponents. channel.tsdo Discord pode importar UI nativa viaDiscordUiContainer, o que puxa dependências de UI de runtime para o plano de controle do Plugin de canal.- O agente e a CLI expõem rotas de escape de payload nativas, como
componentsdo Discord,blocksdo Slack,buttonsdo Telegram ou Mattermost ecarddo Teams ou Feishu. ReplyPayload.channelDatacarrega tanto dicas de transporte quanto envelopes de UI nativos.- O modelo genérico
interactiveexiste, mas é mais estreito que os layouts mais ricos já usados por Discord, Slack, Teams, Feishu, LINE, Telegram e Mattermost.
Objetivos
- O core decide a melhor apresentação semântica para uma mensagem a partir de capacidades declaradas.
- Extensões declaram capacidades e renderizam apresentação semântica em payloads nativos de transporte.
- A Control UI web permanece separada da UI nativa de chat.
- Payloads nativos de canal não são expostos pela superfície compartilhada de agente ou CLI.
- Recursos de apresentação não compatíveis sofrem degradação automática para a melhor representação em texto.
- Comportamento de entrega, como fixar uma mensagem enviada, é metadado genérico de entrega, não apresentação.
Não objetivos
- Nenhum shim de compatibilidade retroativa para
buildCrossContextComponents. - Nenhuma rota de escape nativa pública para
components,blocks,buttonsoucard. - Nenhuma importação no core de bibliotecas de UI nativas de canal.
- Nenhum seam de SDK específico de provedor para canais empacotados.
Modelo-alvo
Adicione um campopresentation controlado pelo core a ReplyPayload.
interactive torna-se um subconjunto de presentation durante a migração:
- O bloco de texto
interactivemapeia parapresentation.blocks[].type = "text". - O bloco de botões
interactivemapeia parapresentation.blocks[].type = "buttons". - O bloco select
interactivemapeia parapresentation.blocks[].type = "select".
presentation; interactive permanece um helper legado interno de parsing/renderização para produtores de resposta existentes.
Metadados de entrega
Adicione um campodelivery controlado pelo core para comportamento de envio que não seja UI.
delivery.pin = truesignifica fixar a primeira mensagem entregue com sucesso.notifyusafalsepor padrão.requiredusafalsepor padrão; canais não compatíveis ou falhas ao fixar sofrem degradação automática continuando a entrega.- Ações manuais de mensagem
pin,unpinelist-pinspermanecem para mensagens existentes.
channelData.telegram.pin = true para delivery.pin = true.
Contrato de capacidade de runtime
Adicione hooks de renderização de apresentação e entrega ao adaptador de saída de runtime, não ao Plugin de canal do plano de controle.- Resolver o canal de destino e o adaptador de runtime.
- Consultar as capacidades de apresentação.
- Degradar blocos não compatíveis antes da renderização.
- Chamar
renderPresentation. - Se não houver renderizador, converter a apresentação em fallback de texto.
- Após envio bem-sucedido, chamar
pinDeliveredMessagequandodelivery.pinfor solicitado e compatível.
Mapeamento de canal
Discord:- Renderizar
presentationem components v2 e contêineres Carbon em módulos apenas de runtime. - Manter helpers de cor de destaque em módulos leves.
- Remover importações de
DiscordUiContainerdo código do plano de controle do Plugin de canal.
- Renderizar
presentationem Block Kit. - Remover entrada
blocksdo agente e da CLI.
- Renderizar texto, contexto e divisores como texto.
- Renderizar ações e select como teclados inline quando configurados e permitidos para a superfície de destino.
- Usar fallback em texto quando botões inline estiverem desativados.
- Mover fixação de tópico ACP para
delivery.pin.
- Renderizar ações como botões interativos quando configurado.
- Renderizar outros blocos como fallback em texto.
- Renderizar
presentationem Adaptive Cards. - Manter ações manuais
pin/unpin/list-pins. - Opcionalmente implementar
pinDeliveredMessagese o suporte do Graph for confiável para a conversa de destino.
- Renderizar
presentationem cards interativos. - Manter ações manuais
pin/unpin/list-pins. - Opcionalmente implementar
pinDeliveredMessagepara fixação de mensagem enviada, se o comportamento da API for confiável.
- Renderizar
presentationem mensagens Flex ou template quando possível. - Fazer fallback para texto em blocos não compatíveis.
- Remover payloads de UI do LINE de
channelData.
- Converter apresentação para texto com formatação conservadora.
Etapas da refatoração
- Reaplicar a correção de release do Discord que separa
ui-colors.tsda UI com suporte de Carbon e removeDiscordUiContainerdeextensions/discord/src/channel.ts. - Adicionar
presentationedeliveryaReplyPayload, normalização de payload de saída, resumos de entrega e payloads de hook. - Adicionar schema
MessagePresentatione helpers de parsing em um subcaminho estreito de SDK/runtime. - Substituir capacidades de mensagem
buttons,cards,componentseblockspor capacidades semânticas de apresentação. - Adicionar hooks do adaptador de saída de runtime para renderização de apresentação e fixação de entrega.
- Substituir a construção de components entre contextos por
buildCrossContextPresentation. - Excluir
src/infra/outbound/channel-adapters.tse removerbuildCrossContextComponentsdos tipos do Plugin de canal. - Alterar
maybeApplyCrossContextMarkerpara anexarpresentationem vez de parâmetros nativos. - Atualizar os caminhos de envio do plugin-dispatch para consumir apenas apresentação semântica e metadados de entrega.
- Remover parâmetros nativos de payload do agente e da CLI:
components,blocks,buttonsecard. - Remover helpers de SDK que criam schemas nativos da ferramenta de mensagem, substituindo-os por helpers de schema de apresentação.
- Remover envelopes nativos/UI de
channelData; manter apenas metadados de transporte até que cada campo remanescente seja revisado. - Migrar renderizadores de Discord, Slack, Telegram, Mattermost, MS Teams, Feishu e LINE.
- Atualizar a documentação para CLI de mensagem, páginas de canal, SDK de Plugin e cookbook de capacidades.
- Executar profiling de expansão de importação para Discord e entrypoints de canal afetados.
channelData de provedor. A etapa 15 continua como validação futura, se quisermos números quantificados de expansão de importação além da barreira de tipos/testes.
Testes
Adicionar ou atualizar:- Testes de normalização de apresentação.
- Testes de degradação automática de apresentação para blocos não compatíveis.
- Testes de marcador entre contextos para caminhos de plugin-dispatch e entrega do core.
- Testes de matriz de renderização de canal para Discord, Slack, Telegram, Mattermost, MS Teams, Feishu, LINE e fallback em texto.
- Testes de schema da ferramenta de mensagem comprovando que campos nativos desapareceram.
- Testes de CLI comprovando que flags nativas desapareceram.
- Regressão de carga preguiçosa do entrypoint do Discord cobrindo Carbon.
- Testes de fixação de entrega cobrindo Telegram e fallback genérico.
Questões em aberto
delivery.pindeve ser implementado para Discord, Slack, MS Teams e Feishu na primeira etapa, ou apenas Telegram primeiro?deliverydeve eventualmente absorver campos existentes comoreplyToId,replyToCurrent,silenteaudioAsVoice, ou continuar focado em comportamentos pós-envio?- A apresentação deve oferecer suporte direto a imagens ou referências de arquivo, ou a mídia deve permanecer separada do layout de UI por enquanto?