Esta página é o design-alvo para substituir auxiliares dispersos de turno de canal, despacho de resposta, streaming de pré-visualização e entrega de saída por um ciclo de vida de mensagem durável. A versão curta: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.
- As primitivas centrais devem ser receber e enviar, não responder.
- Uma resposta é apenas uma relação em uma mensagem de saída.
- Um turno é uma conveniência de processamento de entrada, não o dono da entrega.
- O envio deve ser baseado em contexto:
begin, renderizar, pré-visualizar ou transmitir por stream, envio final, confirmar, falhar. - O recebimento também deve ser baseado em contexto: normalizar, desduplicar, rotear, registrar, despachar, ack da plataforma, falhar.
- O SDK público de Plugin deve se consolidar em uma superfície pequena de mensagens de canal.
Problemas
A pilha atual de canais cresceu a partir de várias necessidades locais válidas:- Adaptadores simples de entrada usam
runtime.channel.turn.run. - Adaptadores ricos usam
runtime.channel.turn.runPrepared. - Auxiliares legados usam
dispatchInboundReplyWithBase,recordInboundSessionAndDispatchReply, auxiliares de payload de resposta, fragmentação de resposta, referências de resposta e auxiliares de runtime de saída. - O streaming de pré-visualização vive em despachantes específicos de canal.
- A durabilidade da entrega final está sendo adicionada em torno dos caminhos existentes de payload de resposta.
Objetivos
- Um ciclo de vida central para todos os caminhos de recebimento e envio de mensagens de canal.
- Envios finais duráveis por padrão no novo ciclo de vida de mensagens depois que um adaptador declarar comportamento seguro para reprodução.
- Semânticas compartilhadas de pré-visualização, edição, stream, finalização, nova tentativa, recuperação e recibo.
- Uma superfície pequena de SDK de Plugin que Plugins de terceiros possam aprender e manter.
- Compatibilidade para chamadores existentes de
channel.turndurante a migração. - Pontos de extensão claros para novas capacidades de canal.
- Nenhum desvio específico de plataforma no núcleo.
- Nenhuma mensagem de canal com delta de tokens. O streaming de canal continua sendo entrega de pré-visualização, edição, acréscimo ou bloco concluído de mensagem.
- Metadados estruturados de origem OpenClaw para saída operacional/de sistema, para que falhas visíveis do Gateway não reentrem em salas compartilhadas habilitadas para bots como prompts novos.
Não objetivos
- Não remover
runtime.channel.turn.*na primeira fase. - Não forçar todos os canais ao mesmo comportamento de transporte nativo.
- Não ensinar ao núcleo tópicos do Telegram, streams nativos do Slack, redações do Matrix, cartões do Feishu, voz do QQ ou atividades do Teams.
- Não publicar todos os auxiliares internos de migração como API estável de SDK.
- Não fazer novas tentativas reproduzirem operações de plataforma não idempotentes já concluídas.
Modelo de referência
O Vercel Chat tem um bom modelo mental público:ChatThreadChannelMessage- métodos de adaptador como
postMessage,editMessage,deleteMessage,stream,startTypinge buscas de histórico - um adaptador de estado para desduplicação, travas, filas e persistência
- Intenções duráveis de envio de saída antes de chamadas diretas de transporte.
- Contextos de envio explícitos com início, confirmação e falha.
- Contextos de recebimento que conhecem a política de ack da plataforma.
- Recibos que sobrevivem a reinicializações e podem orientar edições, exclusões, recuperação e supressão de duplicatas.
- Um SDK público menor. Plugins incluídos podem usar auxiliares internos de runtime, mas Plugins de terceiros devem ver uma API coerente de mensagens.
- Comportamento específico de agente: sessões, transcrições, streaming de blocos, progresso de ferramentas, aprovações, diretivas de mídia, respostas silenciosas e histórico de menções em grupo.
thread.post() não são suficientes para o OpenClaw. Elas escondem o limite transacional que decide se um envio é recuperável.
Modelo central
O novo domínio deve viver sob um namespace central interno, comosrc/channels/message/*.
Ele tem quatro conceitos:
receive é dono do ciclo de vida de entrada.
send é dono do ciclo de vida de saída.
live é dono da pré-visualização, edição, progresso e estado de stream.
state é dono do armazenamento durável de intenções, recibos, idempotência, recuperação, travas e desduplicação.
Termos de mensagem
Mensagem
Uma mensagem normalizada é neutra em relação à plataforma:Alvo
O alvo descreve onde a mensagem vive:Relação
Resposta é uma relação, não uma raiz de API:Origem
Origem descreve quem produziu uma mensagem e como o OpenClaw deve tratar ecos dessa mensagem. Ela é separada da relação: uma mensagem pode ser uma resposta a um usuário e ainda assim ser uma saída operacional originada pelo OpenClaw.allowBots estiver habilitado.
Recibo
Recibos são entidades de primeira classe:Contexto de recebimento
Receber não deve ser uma chamada nua de auxiliar. O núcleo precisa de um contexto que conheça desduplicação, roteamento, registro de sessão e política de ack da plataforma.- Ack de transporte: informa ao Webhook ou socket da plataforma que o OpenClaw aceitou o envelope do evento. Algumas plataformas exigem isso antes do despacho.
- Ack de offset de polling: avança um cursor para que o mesmo evento não seja buscado novamente. Isso não deve avançar para além de trabalho que não possa ser recuperado.
- Ack de registro de entrada: confirma que o OpenClaw persistiu metadados de entrada suficientes para desduplicar e rotear uma reentrega.
- Recibo visível ao usuário: comportamento opcional de leitura/status/digitação; nunca é um limite de durabilidade.
ReceiveAckPolicy controla apenas a confirmação de transporte ou polling. Ela não deve ser reutilizada para recibos de leitura ou reações de status.
Antes da autorização de bot, o recebimento deve aplicar a política compartilhada de eco do OpenClaw quando o canal puder decodificar metadados de origem da mensagem:
allowBots.
A política de ack é explícita:
getUpdates upstream do Telegram ainda é controlado pela biblioteca de polling, então o corte mais profundo restante é uma fonte de polling totalmente durável caso precisemos de reentrega no nível da plataforma além do watermark de reinicialização do OpenClaw. Plataformas de Webhook podem precisar de ack HTTP imediato, mas ainda precisam de desduplicação de entrada e intenções duráveis de envio de saída, porque Webhooks podem reentregar.
Contexto de envio
Enviar também é baseado em contexto:unknown_after_send, não repetidas às cegas. Canais
sem reconciliação podem escolher repetição pelo menos uma vez somente se mensagens visíveis
duplicadas forem uma contrapartida aceitável e documentada para esse canal e relação.
A ponte de reconciliação atual do SDK exige que o adaptador declare
reconcileUnknownSend e então pede que durableFinal.reconcileUnknownSend
classifique uma entrada desconhecida como sent, not_sent ou unresolved; somente not_sent
permite repetição, e entradas não resolvidas permanecem terminais ou repetem somente a
verificação de reconciliação.
A política de durabilidade deve ser explícita:
required significa que o núcleo deve falhar de forma fechada quando não puder gravar a intenção durável.
best_effort pode prosseguir quando a persistência está indisponível. disabled mantém
o comportamento antigo de envio direto. Durante a migração, wrappers legados e helpers públicos
de compatibilidade usam disabled por padrão; eles não devem inferir required do
fato de um canal ter um adaptador genérico de saída.
Contextos de envio também são donos de efeitos pós-envio locais ao canal. Uma migração não é segura
se a entrega durável contornar comportamento local que antes estava associado ao
caminho de envio direto do canal. Exemplos incluem caches de supressão de eco próprio,
marcadores de participação em thread, âncoras de edição nativas, renderização de assinatura do modelo
e guardas contra duplicação específicos da plataforma. Esses efeitos devem se mover para o
adaptador de envio, o adaptador de renderização ou um hook nomeado de contexto de envio antes que
esse canal possa habilitar entrega final genérica durável.
Helpers de envio devem retornar recibos até o chamador. Wrappers duráveis
não podem engolir ids de mensagem nem substituir um resultado de entrega do canal por
undefined; despachantes em buffer usam esses ids para âncoras de thread, edições posteriores,
finalização de pré-visualização e supressão de duplicação.
Envios de fallback operam sobre lotes, não payloads únicos. Reescritas de resposta silenciosa,
fallback de mídia, fallback de cartão e projeção de fragmentos podem produzir mais de
uma mensagem entregável, portanto um contexto de envio deve entregar o lote projetado inteiro
ou documentar explicitamente por que apenas um payload é válido.
unknown_after_send até que o adaptador o reconcilie.
Contexto em tempo real
Comportamento de pré-visualização, edição, progresso e stream deve ser um ciclo de vida opt-in.- Envio do Telegram mais pré-visualização por edição, com final novo após a idade da pré-visualização expirada.
- Envio do Discord mais pré-visualização por edição, cancelamento em mídia/erro/resposta explícita.
- Stream nativo do Slack ou pré-visualização em rascunho dependendo do formato da thread.
- Finalização de postagem em rascunho do Mattermost.
- Finalização de evento em rascunho do Matrix ou redação em caso de incompatibilidade.
- Stream de progresso nativo do Teams.
- Stream do QQ Bot ou fallback acumulado.
Superfície do adaptador
O alvo do SDK público deve ser um subcaminho:origin.decode retornar metadados de origem do OpenClaw. O adaptador de recebimento
fornece fatos da plataforma, como autor bot e formato da sala; o núcleo é dono da decisão de descarte
e da ordenação para que os canais não reimplementem filtros de texto.
Adaptador de origem:
MessageOrigin. Os canais apenas o traduzem para e a partir dos
metadados de transporte nativos. O Slack mapeia isso para chat.postMessage({ metadata }) e
message.metadata de entrada; o Matrix pode mapeá-lo para conteúdo extra de evento; canais
sem metadados nativos podem usar um registro de recibos/saída quando essa for a
melhor aproximação disponível.
Capacidades:
Redução do SDK público
A nova superfície pública deve absorver ou descontinuar estas áreas conceituais:reply-runtimereply-dispatch-runtimereply-referencereply-chunkingreply-payloadinbound-reply-dispatchchannel-reply-pipeline- a maioria dos usos públicos de
outbound-runtime - helpers ad hoc de ciclo de vida de stream em rascunho
plugin-sdk/channel-message quando ele existir.
Relação com o turno do canal
runtime.channel.turn.* deve permanecer durante a migração.
Ele deve se tornar um adaptador de compatibilidade:
channel.turn.runPrepared também deve permanecer inicialmente:
channel.turn poderá ser descontinuado. Ele não deve ser removido até que haja um
caminho de migração do SDK publicado e testes de contrato provando que plugins antigos ainda funcionam
ou falham com um erro de versão claro.
Proteções de compatibilidade
Durante a migração, a entrega genérica durável é opt-in para qualquer canal cujo callback de entrega existente tenha efeitos colaterais além de “enviar este payload”. Pontos de entrada legados não são duráveis por padrão:channel.turn.runedispatchAssembledChannelTurnusam o callback de entrega do canal, a menos que esse canal forneça explicitamente um objeto de política/opções durável auditado.channel.turn.runPreparedpermanece de propriedade do canal até que o despachante preparado chame explicitamente o contexto de envio.- Helpers públicos de compatibilidade como
recordInboundSessionAndDispatchReply,dispatchInboundReplyWithBasee helpers de DM direta nunca injetam entrega genérica durável antes do callbackdeliveroureplyfornecido pelo chamador.
durable: undefined significa “não durável”. O
caminho durável é habilitado somente por um valor explícito de política/opções. durable: false pode permanecer como grafia de compatibilidade, mas a implementação não deve
exigir que todo canal não migrado o adicione.
O código de ponte atual deve manter explícita a decisão de durabilidade:
- A entrega final durável retorna um status discriminado.
handled_visibleehandled_no_sendsão terminais;unsupportedenot_applicablepodem voltar para a entrega de responsabilidade do canal;failedpropaga a falha de envio. - A entrega final durável genérica é controlada por capacidades do adaptador, como entrega silenciosa, preservação do alvo de resposta, preservação de citação nativa e ganchos de envio de mensagens. A falta de paridade deve escolher a entrega de responsabilidade do canal, não um envio genérico que altera o comportamento visível ao usuário.
- Envios duráveis apoiados por fila expõem uma referência de intenção de entrega.
Os campos de sessão
pendingFinalDelivery*existentes podem carregar o id da intenção durante a transição; o estado final é um armazenamentoMessageSendIntentem vez de texto de resposta congelado mais campos de contexto ad hoc.
- O adaptador de envio genérico executa o mesmo comportamento de renderização e transporte que o caminho direto antigo.
- Efeitos colaterais locais pós-envio são preservados por meio do contexto de envio.
- O adaptador retorna recibos ou resultados de entrega com todos os ids de mensagem da plataforma.
- Caminhos de despachante preparados chamam o novo contexto de envio ou permanecem documentados como fora da garantia durável.
- A entrega alternativa lida com todos os payloads projetados, não apenas o primeiro.
- A entrega alternativa durável registra todo o array de payloads projetados como uma intenção ou plano de lote reproduzível.
- A entrega do monitor do iMessage registra mensagens enviadas em um cache de eco depois de um envio bem-sucedido. Envios finais duráveis ainda devem preencher esse cache; caso contrário, o OpenClaw pode reingerir suas próprias respostas finais como mensagens de usuário recebidas.
- O Tlon acrescenta uma assinatura de modelo opcional e registra threads participadas após respostas em grupo. A entrega durável genérica não deve ignorar esses efeitos; mova-os para adaptadores de renderização/envio/finalização do Tlon ou mantenha o Tlon no caminho de responsabilidade do canal.
- O Discord e outros despachantes preparados já são responsáveis pela entrega direta e pelo comportamento de prévia. Eles não são cobertos por uma garantia durável de turno montado até que seus despachantes preparados encaminhem finais explicitamente pelo contexto de envio.
- A entrega alternativa silenciosa do Telegram deve entregar todo o array de payloads projetados. Um atalho de payload único pode descartar payloads alternativos adicionais após a projeção.
- LINE, Zalo, Nostr e outros caminhos montados/de auxiliares existentes podem ter tratamento de tokens de resposta, proxy de mídia, caches de mensagens enviadas, limpeza de carregamento/status ou alvos apenas de callback. Eles permanecem na entrega de responsabilidade do canal até que essas semânticas sejam representadas pelo adaptador de envio e verificadas por testes.
- Auxiliares de DM direta podem ter um callback de resposta que é o único alvo de
transporte correto. A saída genérica não deve inferir a partir de
OriginatingToouToe pular esse callback. - A saída de falha do Gateway do OpenClaw deve permanecer visível para humanos,
mas ecos de sala criados por bot e marcados devem ser descartados antes da
autorização
allowBots. Canais não devem implementar isso com filtros de prefixo de texto visível, exceto como uma medida emergencial curta; o contrato durável é metadado estruturado de origem.
Armazenamento interno
A fila durável deve armazenar intenções de envio de mensagem, não payloads de resposta.Classes de falha
Adaptadores de canal classificam falhas de transporte em categorias fechadas:- Tente novamente
transienterate_limit. - Não tente novamente
invalid_payload, a menos que exista uma alternativa de renderização. - Não tente novamente
authoupermissionaté que a configuração mude. - Para
not_found, permita que a finalização ao vivo passe de edição para um novo envio quando o canal declarar que isso é seguro. - Para
conflict, use regras de recibo/idempotência para decidir se a mensagem já existe. - Qualquer erro depois de o adaptador possivelmente ter concluído E/S da
plataforma, mas antes do commit do recibo, torna-se
unknown_after_send, a menos que o adaptador possa provar que a operação da plataforma não aconteceu.
Mapeamento de canais
| Canal | Migração alvo |
|---|---|
| Telegram | Receber política de confirmação mais envios finais duráveis. O adaptador live é responsável pelo envio e pela edição de pré-visualização, envio final de pré-visualização obsoleta, tópicos, salto de pré-visualização de resposta com citação, fallback de mídia e tratamento de retry-after. |
| Discord | O adaptador de envio encapsula a entrega durável de payload existente. O adaptador live é responsável por edição de rascunho, rascunho de progresso, cancelamento de pré-visualização de mídia/erro, preservação do alvo de resposta e recibos de id de mensagem. Auditar ecos de falha de Gateway escritos por bot em salas compartilhadas; usar um registro de saída ou outro equivalente nativo se Discord não puder carregar metadados de origem em mensagens normais. |
| Slack | O adaptador de envio trata publicações normais de chat. O adaptador live escolhe stream nativo quando o formato da thread oferece suporte; caso contrário, pré-visualização de rascunho. Os recibos preservam timestamps de thread. O adaptador de origem mapeia falhas do Gateway OpenClaw para chat.postMessage.metadata do Slack e descarta ecos marcados em salas de bot antes da autorização allowBots. |
| O adaptador de envio é responsável por envio de texto/mídia com intenções finais duráveis. O adaptador de recebimento trata menção em grupo e identidade do remetente. O live pode permanecer ausente até que WhatsApp tenha um transporte editável. | |
| Matrix | O adaptador live é responsável por edições de eventos de rascunho, finalização, redação, restrições de mídia criptografada e fallback para incompatibilidade de alvo de resposta. O adaptador de recebimento é responsável por hidratação e deduplicação de eventos criptografados. O adaptador de origem deve codificar a origem de falha do Gateway OpenClaw no conteúdo do evento Matrix e descartar ecos de sala de bot configurado antes do tratamento de allowBots. |
| Mattermost | O adaptador live é responsável por uma publicação de rascunho, agrupamento de progresso/ferramenta, finalização no local e fallback de envio novo. |
| Microsoft Teams | O adaptador live é responsável por progresso nativo e comportamento de stream de blocos. O adaptador de envio é responsável por atividades e recibos de anexos/cartões. |
| Feishu | O adaptador de renderização é responsável por renderização de texto/cartão/bruta. O adaptador live é responsável por cartões de streaming e supressão de final duplicado. O adaptador de envio é responsável por comentários, sessões de tópico, mídia e supressão de voz. |
| QQ Bot | O adaptador live é responsável por streaming C2C, timeout do acumulador e envio final de fallback. O adaptador de renderização é responsável por tags de mídia e texto como voz. |
| Signal | Adaptador simples de recebimento e envio. Sem adaptador live, a menos que signal-cli adicione suporte confiável a edição. |
| iMessage | Adaptador simples de recebimento e envio. O envio do iMessage deve preservar a população do cache de eco do monitor antes que finais duráveis possam ignorar a entrega pelo monitor. |
| Google Chat | Adaptador simples de recebimento e envio com relação de thread mapeada para espaços e ids de thread. Auditar o comportamento de sala com allowBots=true para ecos marcados de falha do Gateway OpenClaw. |
| LINE | Adaptador simples de recebimento e envio com restrições de token de resposta modeladas como capacidade de alvo/relação. |
| Nextcloud Talk | Ponte de recebimento SDK mais adaptador de envio. |
| IRC | Adaptador simples de recebimento e envio, sem recibos duráveis de edição. |
| Nostr | Adaptador de recebimento e envio para DMs criptografadas; recibos são ids de evento. |
| QA Channel | Adaptador de teste de contrato para comportamento de recebimento, envio, live, repetição e recuperação. |
| Synology Chat | Adaptador simples de recebimento e envio. |
| Tlon | O adaptador de envio deve preservar a renderização de assinatura do modelo e o rastreamento de threads participantes antes que a entrega final durável genérica seja habilitada. |
| Twitch | Adaptador simples de recebimento e envio com classificação de limite de taxa. |
| Zalo | Adaptador simples de recebimento e envio. |
| Zalo Personal | Adaptador simples de recebimento e envio. |
Plano de migração
Fase 1: Domínio interno de mensagens
- Adicionar tipos
src/channels/message/*para mensagens, alvos, relações, origens, recibos, capacidades, intenções duráveis, contexto de recebimento, contexto de envio, contexto live e classes de falha. - Adicionar
origin?: MessageOriginao tipo de payload da ponte de migração usado pela entrega de resposta atual; depois mover esse campo paraChannelMessagee tipos de mensagens renderizadas conforme a refatoração substitui payloads de resposta. - Manter isso interno até que adaptadores e testes comprovem o formato.
- Adicionar testes unitários puros para transições de estado e serialização.
Fase 2: Núcleo de envio durável
- Mover a fila de saída existente da durabilidade de payload de resposta para intenções duráveis de envio de mensagens.
- Permitir que uma intenção durável de envio carregue um array de payloads projetados ou plano de lote, não apenas um payload de resposta.
- Preservar o comportamento atual de recuperação da fila por meio de conversão de compatibilidade.
- Fazer
deliverOutboundPayloadschamarmessages.send. - Tornar a durabilidade de envio final o padrão e falhar de forma fechada quando a intenção durável não puder ser escrita no novo ciclo de vida de mensagens, depois que o adaptador declarar segurança de repetição. Caminhos existentes de turno de canal e compatibilidade SDK permanecem como envio direto por padrão durante esta fase.
- Registrar recibos de forma consistente.
- Retornar recibos e resultados de entrega ao chamador original do dispatcher em vez de tratar o envio durável como efeito colateral terminal.
- Persistir a origem da mensagem por meio de intenções duráveis de envio para que recuperação, repetição e envios fragmentados preservem a proveniência operacional do OpenClaw.
Fase 3: Ponte de turno de canal
- Reimplementar
channel.turn.runedispatchAssembledChannelTurnsobremessages.receiveemessages.send. - Manter estáveis os tipos de fatos atuais.
- Manter o comportamento legado por padrão. Um canal de turno montado se torna durável somente quando seu adaptador opta explicitamente por isso com uma política de durabilidade segura para repetição.
- Manter
durable: falsecomo uma saída de compatibilidade para caminhos que finalizam edições nativas e ainda não podem repetir com segurança, mas não depender de marcadoresfalsepara proteger canais não migrados. - Tornar a durabilidade de turno montado padrão somente no novo ciclo de vida de mensagens, depois que o mapeamento de canal comprovar que o caminho genérico de envio preserva a semântica antiga de entrega do canal.
Fase 4: Ponte de dispatcher preparado
- Substitua
deliverDurableInboundReplyPayloadpor uma ponte de contexto de envio. - Mantenha o helper antigo como um wrapper.
- Migre Telegram, WhatsApp, Slack, Signal, iMessage e Discord primeiro, porque eles já têm trabalho de final durável ou caminhos de envio mais simples.
- Trate todo dispatcher preparado como descoberto até que ele opte explicitamente pelo contexto de envio. A documentação e as entradas do changelog devem dizer “turnos de canal montados” ou nomear os caminhos de canal migrados, em vez de afirmar todas as respostas finais automáticas.
- Mantenha
recordInboundSessionAndDispatchReply, helpers de DM direto e helpers públicos de compatibilidade semelhantes preservando o comportamento. Eles podem expor uma adesão explícita ao contexto de envio mais tarde, mas não devem tentar automaticamente a entrega durável genérica antes do callback de entrega de propriedade do chamador.
Fase 5: Ciclo de Vida Live Unificado
- Crie
messages.livecom dois adaptadores de prova:- Telegram para envio mais edição mais envio final obsoleto.
- Matrix para finalização de rascunho mais fallback de redação.
- Depois migre Discord, Slack, Mattermost, Teams, QQ Bot e Feishu.
- Exclua o código duplicado de finalização de prévia somente depois que cada canal tiver testes de paridade.
Fase 6: SDK Público
- Adicione
openclaw/plugin-sdk/channel-message. - Documente-o como a API preferida de plugin de canal.
- Atualize exports do pacote, inventário de entrypoints, baselines de API geradas e documentação do SDK de plugin.
- Inclua
MessageOrigin, hooks de codificação/decodificação de origem e o predicado compartilhadoshouldDropOpenClawEchona superfície do SDK channel-message. - Mantenha wrappers de compatibilidade para subpaths antigos.
- Marque helpers do SDK nomeados por resposta como obsoletos na documentação depois que os plugins incluídos forem migrados.
Fase 7: Todos os Remetentes
Mova todos os produtores de saída que não sejam respostas paramessages.send:
- notificações de cron e heartbeat
- conclusões de tarefas
- resultados de hooks
- prompts de aprovação e resultados de aprovação
- envios da ferramenta de mensagens
- anúncios de conclusão de subagentes
- envios explícitos da CLI ou da UI de Controle
- caminhos de automação/broadcast
Fase 8: Depreciar Turn
- Mantenha
channel.turncomo um wrapper por pelo menos uma janela de compatibilidade. - Publique notas de migração.
- Execute testes de compatibilidade do SDK de plugin contra imports antigos.
- Remova ou oculte helpers internos antigos somente depois que nenhum plugin incluído precisar deles e os contratos de terceiros tiverem uma substituição estável.
Plano de testes
Testes unitários:- Serialização e recuperação de intenção de envio durável.
- Reutilização de chave de idempotência e supressão de duplicatas.
- Commit de recibo e salto de replay.
- Recuperação de
unknown_after_sendque reconcilia antes do replay quando um adaptador oferece suporte à reconciliação. - Política de classificação de falhas.
- Sequenciamento da política de ack de recebimento.
- Mapeamento de relações para envios de resposta, followup, sistema e broadcast.
- Fábrica de origem de falha de Gateway e predicado
shouldDropOpenClawEcho. - Preservação da origem por normalização de payload, chunking, serialização de fila durável e recuperação.
- Adaptador simples de
channel.turn.runainda registra e envia. - Entrega legada de turno montado não se torna durável, a menos que o canal opte explicitamente por isso.
- Ponte de
channel.turn.runPreparedainda registra e finaliza. - Helpers públicos de compatibilidade chamam callbacks de entrega de propriedade do chamador por padrão e não fazem envio genérico antes desses callbacks.
- Entrega durável de fallback reproduz todo o array de payloads projetados após reinício e não pode deixar os payloads posteriores sem registro após uma falha inicial.
- Entrega durável de turno montado retorna ids de mensagem da plataforma ao dispatcher em buffer.
- Hooks de entrega personalizados ainda retornam ids de mensagem da plataforma quando a entrega durável está desativada ou indisponível.
- Resposta final sobrevive a reinício entre a conclusão do assistente e o envio para a plataforma.
- Rascunho de prévia finaliza no lugar quando permitido.
- Rascunho de prévia é cancelado ou redigido quando incompatibilidade de mídia/erro/alvo de resposta exige entrega normal.
- Streaming de blocos e streaming de prévia não entregam ambos o mesmo texto.
- Mídia transmitida antecipadamente não é duplicada na entrega final.
- Resposta a tópico do Telegram com ack de polling atrasado até a marca d’água concluída segura do contexto de recebimento.
- Recuperação de polling do Telegram para atualizações aceitas mas não entregues coberta pelo modelo persistido de offset concluído seguro.
- Prévia obsoleta do Telegram envia final nova e limpa a prévia.
- Fallback silencioso do Telegram envia todo payload de fallback projetado.
- Durabilidade do fallback silencioso do Telegram registra atomically todo o array de fallback projetado, não uma intenção durável de payload único por iteração do loop.
- Cancelamento de prévia do Discord em mídia/erro/resposta explícita.
- Finais de dispatcher preparado do Discord passam pelo contexto de envio antes que documentação ou changelog afirmem durabilidade de resposta final do Discord.
- Envios finais duráveis do iMessage populam o cache de eco de mensagem enviada do monitor.
- Caminhos legados de entrega de LINE, Zalo e Nostr não são contornados por envio durável genérico até que existam testes de paridade dos adaptadores.
- Entrega por callback de Direct-DM/Nostr continua autoritativa, a menos que seja explicitamente migrada para um alvo de mensagem completo e um adaptador de envio seguro para replay.
- Mensagens marcadas de falha de gateway do OpenClaw no Slack permanecem visíveis
na saída, ecos marcados da sala do bot caem antes de
allowBots, e mensagens não marcadas de bots com o mesmo texto visível ainda seguem a autorização normal de bot. - Fallback de stream nativo do Slack para prévia de rascunho em DMs de nível superior.
- Finalização de prévia do Matrix e fallback de redação.
- Ecos de sala de falha de gateway do OpenClaw marcados no Matrix vindos de
contas de bot configuradas caem antes do tratamento de
allowBots. - Auditorias em cascata de falha de gateway em sala compartilhada de Discord e
Google Chat cobrem modos
allowBotsantes de afirmar proteção genérica ali. - Finalização de rascunho do Mattermost e fallback de envio novo.
- Finalização de progresso nativo do Teams.
- Supressão de final duplicado do Feishu.
- Fallback de timeout do acumulador do QQ Bot.
- Envios finais duráveis do Tlon preservam renderização de assinatura do modelo e rastreamento de thread participada.
- Envios finais duráveis simples de WhatsApp, Signal, iMessage, Google Chat, LINE, IRC, Nostr, Nextcloud Talk, Synology Chat, Tlon, Twitch, Zalo e Zalo Personal.
- Arquivos Vitest direcionados durante o desenvolvimento.
pnpm check:changedno Testbox para toda a superfície alterada.pnpm checkmais amplo no Testbox antes de integrar a refatoração completa ou após mudanças de SDK/export públicos.- Smoke live ou qa-channel para pelo menos um canal capaz de edição e um canal simples somente de envio antes de remover wrappers de compatibilidade.
Questões em aberto
- Se o Telegram deve eventualmente substituir a origem do runner grammY por uma origem de polling totalmente durável que possa controlar a reentrega no nível da plataforma, não apenas a marca d’água de reinício persistida do OpenClaw.
- Se o estado durável de prévia live deve ser armazenado no mesmo registro de fila da intenção de envio final ou em um armazenamento irmão de estado live.
- Por quanto tempo wrappers de compatibilidade permanecem documentados após
plugin-sdk/channel-messageser lançado. - Se plugins de terceiros devem implementar adaptadores de recebimento
diretamente ou apenas fornecer hooks de normalização/envio/live por meio de
defineChannelMessageAdapter. - Quais campos de recibo são seguros para expor no SDK público versus estado de runtime interno.
- Se efeitos colaterais como caches de autoeco e marcadores de thread participada devem ser modelados como hooks de contexto de envio, etapas de finalização de propriedade do adaptador ou assinantes de recibo.
- Quais canais têm metadados de origem nativos, quais precisam de registries de saída persistidos e quais não conseguem oferecer supressão confiável de eco entre bots.
Critérios de aceitação
- Todo canal de mensagens incluído envia saída final visível por meio de
messages.send. - Todo canal de mensagens de entrada entra por
messages.receiveou por um wrapper de compatibilidade documentado. - Todo canal de prévia/edição/stream usa
messages.livepara estado de rascunho e finalização. channel.turné apenas um wrapper.- Helpers do SDK nomeados por resposta são exports de compatibilidade, não o caminho recomendado.
- A recuperação durável consegue reproduzir envios finais pendentes após reinício sem perder a resposta final ou duplicar envios já com commit; envios cujo resultado na plataforma é desconhecido são reconciliados antes do replay ou documentados como pelo menos uma vez para esse adaptador.
- Envios finais duráveis falham fechados quando a intenção durável não pode ser gravada, a menos que um chamador tenha selecionado explicitamente um modo não durável documentado.
- Helpers legados de channel-turn e compatibilidade do SDK usam entrega direta de propriedade do canal por padrão; envio durável genérico é somente adesão explícita.
- Recibos preservam todos os ids de mensagem da plataforma para entregas em várias partes e um id primário para conveniência de threading/edição.
- Wrappers duráveis preservam efeitos colaterais locais do canal antes de substituir callbacks de entrega direta.
- Dispatchers preparados não são contados como duráveis até que seu caminho de entrega final use explicitamente o contexto de envio.
- Entrega de fallback lida com todo payload projetado.
- Entrega durável de fallback registra todo payload projetado em uma intenção ou plano de lote reproduzível.
- Saída de falha de gateway originada pelo OpenClaw é visível para humanos, mas ecos de sala marcados e criados por bot são descartados antes da autorização de bot em canais que declaram suporte ao contrato de origem.
- A documentação explica envio, recebimento, live, estado, recibos, relações, política de falhas, migração e cobertura de testes.