Ta strona jest docelowym projektem zastąpienia rozproszonych pomocników tury kanału, wysyłania odpowiedzi, strumieniowania podglądu i dostarczania wychodzącego jednym trwałym cyklem życia wiadomości. W skrócie:Documentation Index
Fetch the complete documentation index at: https://docs.openclaw.ai/llms.txt
Use this file to discover all available pages before exploring further.
- Podstawowymi prymitywami rdzenia powinny być odbieranie i wysyłanie, a nie odpowiadanie.
- Odpowiedź jest tylko relacją w wiadomości wychodzącej.
- Tura to udogodnienie przetwarzania przychodzącego, a nie właściciel dostarczania.
- Wysyłanie musi być oparte na kontekście:
begin, renderowanie, podgląd lub strumieniowanie, wysłanie końcowe, zatwierdzenie, niepowodzenie. - Odbieranie także musi być oparte na kontekście: normalizacja, deduplikacja, routing, zapis, wysłanie do obsługi, potwierdzenie platformy, niepowodzenie.
- Publiczny SDK pluginów powinien zostać sprowadzony do jednej małej powierzchni wiadomości kanału.
Problemy
Obecny stos kanałów wyrósł z kilku zasadnych lokalnych potrzeb:- Proste adaptery przychodzące używają
runtime.channel.turn.run. - Rozbudowane adaptery używają
runtime.channel.turn.runPrepared. - Starsze pomocniki używają
dispatchInboundReplyWithBase,recordInboundSessionAndDispatchReply, pomocników ładunku odpowiedzi, dzielenia odpowiedzi na fragmenty, odwołań odpowiedzi oraz pomocników środowiska uruchomieniowego dla wiadomości wychodzących. - Strumieniowanie podglądu znajduje się w dyspozytorach specyficznych dla kanałów.
- Trwałość końcowego dostarczania jest dodawana wokół istniejących ścieżek ładunku odpowiedzi.
Cele
- Jeden cykl życia rdzenia dla wszystkich ścieżek odbierania i wysyłania wiadomości kanału.
- Trwałe końcowe wysyłki domyślnie w nowym cyklu życia wiadomości po tym, jak adapter zadeklaruje zachowanie bezpieczne do ponownego odtwarzania.
- Wspólna semantyka podglądu, edycji, strumienia, finalizacji, ponowień, odzyskiwania i potwierdzeń.
- Mała powierzchnia SDK pluginów, którą pluginy firm trzecich mogą poznać i utrzymywać.
- Zgodność dla istniejących wywołań
channel.turnpodczas migracji. - Jasne punkty rozszerzeń dla nowych możliwości kanałów.
- Brak gałęzi specyficznych dla platform w rdzeniu.
- Brak wiadomości kanału typu token-delta. Strumieniowanie kanału pozostaje podglądem wiadomości, edycją, dopisaniem albo dostarczeniem ukończonego bloku.
- Ustrukturyzowane metadane pochodzenia OpenClaw dla wyjścia operacyjnego/systemowego, aby widoczne awarie Gateway nie wracały do współdzielonych pokoi z włączonym botem jako nowe prompty.
Poza zakresem
- Nie usuwać
runtime.channel.turn.*w pierwszej fazie. - Nie wymuszać na każdym kanale tego samego natywnego zachowania transportu.
- Nie uczyć rdzenia tematów Telegram, natywnych strumieni Slack, redakcji Matrix, kart Feishu, głosu QQ ani aktywności Teams.
- Nie publikować wszystkich wewnętrznych pomocników migracji jako stabilnego API SDK.
- Nie sprawiać, by ponowienia odtwarzały zakończone nieidempotentne operacje platformy.
Model referencyjny
Vercel Chat ma dobry publiczny model mentalny:ChatThreadChannelMessage- metody adaptera, takie jak
postMessage,editMessage,deleteMessage,stream,startTypingi pobieranie historii - adapter stanu dla deduplikacji, blokad, kolejek i utrwalania
- Trwałe intencje wysyłania wychodzącego przed bezpośrednimi wywołaniami transportu.
- Jawne konteksty wysyłania z rozpoczęciem, zatwierdzeniem i niepowodzeniem.
- Konteksty odbierania, które znają politykę potwierdzania platformy.
- Potwierdzenia, które przetrwają restart i mogą sterować edycjami, usunięciami, odzyskiwaniem oraz tłumieniem duplikatów.
- Mniejszy publiczny SDK. Dołączone pluginy mogą używać wewnętrznych pomocników środowiska uruchomieniowego, ale pluginy firm trzecich powinny widzieć jedno spójne API wiadomości.
- Zachowanie specyficzne dla agentów: sesje, transkrypty, strumieniowanie bloków, postęp narzędzi, zatwierdzenia, dyrektywy mediów, ciche odpowiedzi i historia wzmianek grupowych.
thread.post() nie wystarczają dla OpenClaw. Ukrywają granicę transakcji, która decyduje, czy wysyłanie jest możliwe do odzyskania.
Model rdzenia
Nowa domena powinna żyć pod wewnętrzną przestrzenią nazw rdzenia, taką jaksrc/channels/message/*.
Ma cztery pojęcia:
receive odpowiada za cykl życia przychodzący.
send odpowiada za cykl życia wychodzący.
live odpowiada za stan podglądu, edycji, postępu i strumienia.
state odpowiada za trwałe przechowywanie intencji, potwierdzenia, idempotencję, odzyskiwanie, blokady i deduplikację.
Terminy wiadomości
Wiadomość
Znormalizowana wiadomość jest neutralna względem platformy:Cel
Cel opisuje, gdzie znajduje się wiadomość:Relacja
Odpowiedź jest relacją, a nie korzeniem API:Pochodzenie
Pochodzenie opisuje, kto wytworzył wiadomość i jak OpenClaw powinien traktować echa tej wiadomości. Jest oddzielone od relacji: wiadomość może być odpowiedzią do użytkownika i nadal być pochodzącym z OpenClaw wyjściem operacyjnym.allowBots jest włączone.
Potwierdzenie
Potwierdzenia są pierwszorzędne:Kontekst odbierania
Odbieranie nie powinno być gołym wywołaniem pomocnika. Rdzeń potrzebuje kontekstu, który zna deduplikację, routing, zapis sesji i politykę potwierdzania platformy.- Potwierdzenie transportu: informuje Webhook lub gniazdo platformy, że OpenClaw zaakceptował kopertę zdarzenia. Niektóre platformy wymagają tego przed wysłaniem do obsługi.
- Potwierdzenie offsetu odpytywania: przesuwa kursor, aby to samo zdarzenie nie zostało pobrane ponownie. Nie może to przesunąć się za pracę, której nie da się odzyskać.
- Potwierdzenie zapisu przychodzącego: potwierdza, że OpenClaw utrwalił wystarczająco dużo metadanych przychodzących, aby deduplikować i trasować ponowne dostarczenie.
- Potwierdzenie widoczne dla użytkownika: opcjonalne zachowanie odczytu/statusu/pisania; nigdy nie jest granicą trwałości.
ReceiveAckPolicy kontroluje wyłącznie potwierdzenie transportu lub odpytywania. Nie wolno go ponownie używać do potwierdzeń odczytu ani reakcji statusu.
Przed autoryzacją bota odbieranie musi zastosować wspólną politykę echa OpenClaw, gdy kanał może zdekodować metadane pochodzenia wiadomości:
allowBots.
Polityka potwierdzania jest jawna:
getUpdates Telegram nadal jest kontrolowany przez bibliotekę odpytywania, więc pozostałym głębszym cięciem jest w pełni trwałe źródło odpytywania, jeśli potrzebujemy ponownego dostarczania na poziomie platformy poza znakiem wodnym restartu OpenClaw. Platformy Webhook mogą wymagać natychmiastowego potwierdzenia HTTP, ale nadal potrzebują deduplikacji przychodzącej i trwałych intencji wysyłania wychodzącego, ponieważ Webhooki mogą dostarczać ponownie.
Kontekst wysyłania
Wysyłanie także jest oparte na kontekście:unknown_after_send, a nie ślepo odtworzone. Kanały
bez uzgadniania mogą wybrać ponowienie w trybie co najmniej raz tylko wtedy, gdy zduplikowane widoczne
wiadomości są akceptowalnym, udokumentowanym kompromisem dla tego kanału i relacji.
Obecny most uzgadniania SDK wymaga, aby adapter zadeklarował
reconcileUnknownSend, a następnie prosi durableFinal.reconcileUnknownSend o
sklasyfikowanie nieznanego wpisu jako sent, not_sent albo unresolved; tylko not_sent
pozwala na ponowienie, a nierozwiązane wpisy pozostają terminalne albo ponawiają wyłącznie
sprawdzenie uzgodnienia.
Polityka trwałości musi być jawna:
required oznacza, że rdzeń musi zakończyć się bezpieczną porażką, gdy nie może zapisać trwałej intencji.
best_effort może przejść dalej, gdy trwałe przechowywanie jest niedostępne. disabled zachowuje
stare zachowanie bezpośredniej wysyłki. Podczas migracji starsze wrappery i publiczne
helpery zgodności domyślnie używają disabled; nie mogą wnioskować required z
faktu, że kanał ma ogólny adapter wychodzący.
Konteksty wysyłki są też właścicielami lokalnych dla kanału efektów po wysłaniu. Migracja nie jest bezpieczna,
jeśli trwałe dostarczanie omija lokalne zachowanie, które wcześniej było podpięte do
bezpośredniej ścieżki wysyłki kanału. Przykłady obejmują pamięci podręczne tłumienia własnego echa,
znaczniki udziału w wątku, natywne kotwice edycji, renderowanie sygnatury modelu
i specyficzne dla platformy zabezpieczenia przed duplikatami. Te efekty muszą zostać przeniesione do
adaptera wysyłki, adaptera renderowania albo nazwanego haka kontekstu wysyłki, zanim
kanał będzie mógł włączyć trwałe ogólne dostarczanie końcowe.
Helpery wysyłki muszą zwracać potwierdzenia aż do swojego wywołującego. Trwałe
wrappery nie mogą ukrywać identyfikatorów wiadomości ani zastępować wyniku dostarczenia kanału
wartością undefined; buforowane dyspozytory używają tych identyfikatorów do kotwic wątków, późniejszych edycji,
finalizacji podglądu i tłumienia duplikatów.
Wysyłki awaryjne działają na partiach, nie na pojedynczych ładunkach. Przepisywanie cichych odpowiedzi,
awaryjna obsługa multimediów, awaryjna obsługa kart i projekcja fragmentów mogą wszystkie wygenerować więcej niż
jedną możliwą do dostarczenia wiadomość, więc kontekst wysyłki musi albo dostarczyć całą
rzutowaną partię, albo jawnie udokumentować, dlaczego poprawny jest tylko jeden ładunek.
unknown_after_send, dopóki adapter jej nie uzgodni.
Kontekst na żywo
Zachowanie podglądu, edycji, postępu i strumienia powinno być jednym opcjonalnym cyklem życia.- Telegram wysyła i edytuje podgląd, ze świeżą wersją końcową po przekroczeniu wieku nieaktualności podglądu.
- Discord wysyła i edytuje podgląd, anuluje przy multimediach, błędzie albo jawnej odpowiedzi.
- Slack używa natywnego strumienia albo roboczego podglądu zależnie od kształtu wątku.
- Finalizacja roboczego wpisu Mattermost.
- Finalizacja roboczego zdarzenia Matrix albo redakcja przy niezgodności.
- Natywny strumień postępu Teams.
- Strumień QQ Bot albo zebrana ścieżka awaryjna.
Powierzchnia adaptera
Publicznym celem SDK powinna być jedna podścieżka:origin.decode zwraca metadane pochodzenia OpenClaw. Adapter odbioru
dostarcza fakty platformy, takie jak autor bot i kształt pokoju; rdzeń jest właścicielem decyzji
o odrzuceniu i kolejności, aby kanały nie implementowały ponownie filtrów tekstu.
Adapter pochodzenia:
MessageOrigin. Kanały tylko tłumaczą je na natywne metadane
transportu i z powrotem. Slack mapuje to na chat.postMessage({ metadata }) i
przychodzące message.metadata; Matrix może mapować to na dodatkową treść zdarzenia; kanały
bez natywnych metadanych mogą używać rejestru potwierdzeń/wychodzącego, gdy jest to
najlepsze dostępne przybliżenie.
Możliwości:
Redukcja publicznego SDK
Nowa publiczna powierzchnia powinna wchłonąć albo wycofać te obszary koncepcyjne:reply-runtimereply-dispatch-runtimereply-referencereply-chunkingreply-payloadinbound-reply-dispatchchannel-reply-pipeline- większość publicznych użyć
outbound-runtime - doraźne helpery cyklu życia roboczego strumienia
plugin-sdk/channel-message, gdy tylko ono powstanie.
Relacja z turą kanału
runtime.channel.turn.* powinno pozostać podczas migracji.
Powinno stać się adapterem zgodności:
channel.turn.runPrepared również początkowo powinno pozostać:
channel.turn można wycofać. Nie powinno zostać usunięte, dopóki nie będzie
opublikowanej ścieżki migracji SDK i testów kontraktu dowodzących, że stare Pluginy nadal działają
albo kończą się jasnym błędem wersji.
Bariery zgodności
Podczas migracji ogólne trwałe dostarczanie jest opcjonalne dla każdego kanału, którego istniejące wywołanie zwrotne dostarczania ma efekty uboczne wykraczające poza „wyślij ten ładunek”. Starsze punkty wejścia są domyślnie nietrwałe:channel.turn.runidispatchAssembledChannelTurnużywają wywołania zwrotnego dostarczania kanału, chyba że ten kanał jawnie dostarczy zweryfikowany trwały obiekt polityki/opcji.channel.turn.runPreparedpozostaje własnością kanału, dopóki przygotowany dyspozytor jawnie nie wywoła kontekstu wysyłki.- Publiczne helpery zgodności, takie jak
recordInboundSessionAndDispatchReply,dispatchInboundReplyWithBasei helpery bezpośrednich wiadomości prywatnych nigdy nie wstrzykują ogólnego trwałego dostarczania przed dostarczonym przez wywołującego wywołaniem zwrotnymdeliveralboreply.
durable: undefined oznacza „nietrwałe”. Ścieżka
trwała jest włączana tylko przez jawną wartość polityki/opcji. durable: false może pozostać jako zapis zgodności, ale implementacja nie powinna
wymagać od każdego niezmmigrowanego kanału jego dodania.
Obecny kod mostu musi utrzymywać jawną decyzję o trwałości:
- Trwałe dostarczanie odpowiedzi końcowej zwraca dyskryminowany status.
handled_visibleihandled_no_sendsą terminalne;unsupportedinot_applicablemogą przejść awaryjnie do dostarczania obsługiwanego przez kanał;failedpropaguje błąd wysyłki. - Ogólne trwałe dostarczanie odpowiedzi końcowej jest ograniczane przez możliwości adaptera, takie jak ciche dostarczanie, zachowanie celu odpowiedzi, zachowanie natywnego cytatu oraz haki wysyłania wiadomości. Brak parytetu powinien wybierać dostarczanie obsługiwane przez kanał, a nie ogólną wysyłkę zmieniającą zachowanie widoczne dla użytkownika.
- Trwałe wysyłki oparte na kolejce ujawniają referencję intencji dostarczenia. Istniejące
pola sesji
pendingFinalDelivery*mogą przenosić identyfikator intencji w trakcie przejścia; stanem docelowym jest magazynMessageSendIntentzamiast zamrożonego tekstu odpowiedzi oraz doraźnych pól kontekstu.
- Ogólny adapter wysyłki wykonuje takie samo renderowanie i zachowanie transportowe jak stara ścieżka bezpośrednia.
- Lokalne skutki uboczne po wysyłce są zachowane przez kontekst wysyłki.
- Adapter zwraca potwierdzenia lub wyniki dostarczenia ze wszystkimi identyfikatorami wiadomości platformy.
- Przygotowane ścieżki dyspozytora albo wywołują nowy kontekst wysyłki, albo pozostają udokumentowane jako poza trwałą gwarancją.
- Dostarczanie awaryjne obsługuje każdy rzutowany ładunek, a nie tylko pierwszy.
- Trwałe dostarczanie awaryjne zapisuje całą tablicę rzutowanych ładunków jako jedną odtwarzalną intencję albo plan wsadowy.
- Dostarczanie monitora iMessage zapisuje wysłane wiadomości w pamięci podręcznej echa po udanej wysyłce. Trwałe wysyłki końcowe nadal muszą wypełniać tę pamięć podręczną, w przeciwnym razie OpenClaw może ponownie pobrać własne odpowiedzi końcowe jako przychodzące wiadomości użytkownika.
- Tlon dołącza opcjonalny podpis modelu i zapisuje wątki z udziałem po odpowiedziach grupowych. Ogólne trwałe dostarczanie nie może pomijać tych efektów; albo przenieś je do adapterów renderowania/wysyłania/finalizacji Tlon, albo pozostaw Tlon na ścieżce obsługiwanej przez kanał.
- Discord i inne przygotowane dyspozytory już posiadają bezpośrednie dostarczanie i zachowanie podglądu. Nie są objęte trwałą gwarancją złożonej tury, dopóki ich przygotowane dyspozytory jawnie nie skierują odpowiedzi końcowych przez kontekst wysyłki.
- Ciche dostarczanie awaryjne Telegram musi dostarczyć pełną tablicę rzutowanych ładunków. Skrót dla pojedynczego ładunku może porzucić dodatkowe ładunki awaryjne po rzutowaniu.
- LINE, BlueBubbles, Zalo, Nostr i inne istniejące ścieżki złożone/pomocnicze mogą mieć obsługę tokenów odpowiedzi, pośredniczenie mediów, pamięci podręczne wysłanych wiadomości, czyszczenie ładowania/statusu albo cele wyłącznie callbackowe. Pozostają na dostarczaniu obsługiwanym przez kanał, dopóki te semantyki nie zostaną odzwierciedlone przez adapter wysyłki i zweryfikowane testami.
- Pomocniki bezpośrednich DM mogą mieć callback odpowiedzi, który jest jedynym poprawnym celem
transportu. Ogólne wysyłanie wychodzące nie może zgadywać na podstawie
OriginatingToalboToi pomijać tego callbacku. - Dane wyjściowe awarii OpenClaw Gateway muszą pozostać widoczne dla ludzi, ale oznaczone
echa pokojów autorstwa bota muszą zostać odrzucone przed autoryzacją
allowBots. Kanały nie mogą implementować tego przy użyciu filtrów prefiksów widocznego tekstu poza krótkim awaryjnym obejściem; trwały kontrakt to ustrukturyzowane metadane pochodzenia.
Wewnętrzna pamięć
Trwała kolejka powinna przechowywać intencje wysyłania wiadomości, a nie ładunki odpowiedzi.Klasy awarii
Adaptery kanałów klasyfikują awarie transportu do zamkniętych kategorii:- Ponawiaj
transientirate_limit. - Nie ponawiaj
invalid_payload, chyba że istnieje awaryjna ścieżka renderowania. - Nie ponawiaj
authanipermission, dopóki konfiguracja się nie zmieni. - Dla
not_foundpozwól finalizacji na żywo przejść awaryjnie z edycji na świeżą wysyłkę, gdy kanał deklaruje, że jest to bezpieczne. - Dla
conflictużyj reguł potwierdzeń/idempotencji, aby zdecydować, czy wiadomość już istnieje. - Każdy błąd po tym, jak adapter mógł ukończyć wejście/wyjście platformy, ale przed
zatwierdzeniem potwierdzenia, staje się
unknown_after_send, chyba że adapter potrafi udowodnić, że operacja platformy nie nastąpiła.
Mapowanie kanałów
| Kanał | Docelowa migracja |
|---|---|
| Telegram | Odbieranie zasad potwierdzeń oraz trwałe wysyłanie komunikatów końcowych. Adapter live odpowiada za wysyłanie oraz edycję podglądu, końcowe wysyłanie nieaktualnego podglądu, tematy, pomijanie podglądu odpowiedzi z cytatem, awaryjną obsługę multimediów i obsługę retry-after. |
| Discord | Adapter wysyłania opakowuje istniejące trwałe dostarczanie ładunków. Adapter live odpowiada za edycję wersji roboczej, wersję roboczą postępu, anulowanie podglądu multimediów/błędu, zachowanie celu odpowiedzi i potwierdzenia identyfikatorów wiadomości. Skontroluj echa awarii Gateway autorstwa bota we współdzielonych pokojach; użyj rejestru wychodzącego lub innego natywnego odpowiednika, jeśli Discord nie może przenosić metadanych pochodzenia w zwykłych wiadomościach. |
| Slack | Adapter wysyłania obsługuje zwykłe wpisy czatu. Adapter live wybiera natywny strumień, gdy kształt wątku go obsługuje, w przeciwnym razie używa podglądu wersji roboczej. Potwierdzenia zachowują znaczniki czasu wątków. Adapter pochodzenia mapuje awarie Gateway OpenClaw na chat.postMessage.metadata w Slack i odrzuca oznaczone echa w pokoju bota przed autoryzacją allowBots. |
| Adapter wysyłania odpowiada za wysyłanie tekstu/multimediów z trwałymi intencjami końcowymi. Adapter odbierania obsługuje wzmiankę w grupie i tożsamość nadawcy. Adapter live może pozostać nieobecny, dopóki WhatsApp nie będzie mieć edytowalnego transportu. | |
| Matrix | Adapter live odpowiada za edycje zdarzeń wersji roboczych, finalizację, redakcję, ograniczenia szyfrowanych multimediów i awaryjną obsługę niezgodności celu odpowiedzi. Adapter odbierania odpowiada za hydratację i deduplikację szyfrowanych zdarzeń. Adapter pochodzenia powinien zakodować pochodzenie awarii Gateway OpenClaw w treści zdarzenia Matrix i odrzucać skonfigurowane echa w pokoju bota przed obsługą allowBots. |
| Mattermost | Adapter live odpowiada za jeden wpis roboczy, zwijanie postępu/narzędzi, finalizację w miejscu i awaryjne świeże wysłanie. |
| Microsoft Teams | Adapter live odpowiada za natywny postęp i zachowanie strumienia bloków. Adapter wysyłania odpowiada za aktywności oraz potwierdzenia załączników/kart. |
| Feishu | Adapter renderowania odpowiada za renderowanie tekstu/kart/surowej treści. Adapter live odpowiada za karty strumieniowe i tłumienie zduplikowanych komunikatów końcowych. Adapter wysyłania odpowiada za komentarze, sesje tematów, multimedia i tłumienie głosu. |
| QQ Bot | Adapter live odpowiada za strumieniowanie C2C, limit czasu akumulatora i awaryjne wysłanie końcowe. Adapter renderowania odpowiada za tagi multimediów i tekst jako głos. |
| Signal | Prosty adapter odbierania i wysyłania. Brak adaptera live, chyba że signal-cli doda niezawodną obsługę edycji. |
| iMessage and BlueBubbles | Prosty adapter odbierania i wysyłania. Wysyłanie iMessage musi zachować wypełnianie pamięci podręcznej ech monitora, zanim trwałe komunikaty końcowe będą mogły ominąć dostarczanie przez monitor. Pisanie, reakcje i załączniki specyficzne dla BlueBubbles pozostają możliwościami adaptera. |
| Google Chat | Prosty adapter odbierania i wysyłania z relacją wątku mapowaną na przestrzenie i identyfikatory wątków. Skontroluj zachowanie pokoju allowBots=true dla oznaczonych ech awarii Gateway OpenClaw. |
| LINE | Prosty adapter odbierania i wysyłania z ograniczeniami tokenu odpowiedzi modelowanymi jako możliwość celu/relacji. |
| Nextcloud Talk | Most odbierania SDK oraz adapter wysyłania. |
| IRC | Prosty adapter odbierania i wysyłania, bez trwałych potwierdzeń edycji. |
| Nostr | Adapter odbierania i wysyłania dla szyfrowanych wiadomości prywatnych; potwierdzenia są identyfikatorami zdarzeń. |
| QA Channel | Adapter testów kontraktowych dla zachowania odbierania, wysyłania, live, ponawiania i odzyskiwania. |
| Synology Chat | Prosty adapter odbierania i wysyłania. |
| Tlon | Adapter wysyłania musi zachować renderowanie sygnatury modelu i śledzenie wątków z udziałem użytkownika, zanim zostanie włączone ogólne trwałe dostarczanie końcowe. |
| Twitch | Prosty adapter odbierania i wysyłania z klasyfikacją limitów szybkości. |
| Zalo | Prosty adapter odbierania i wysyłania. |
| Zalo Personal | Prosty adapter odbierania i wysyłania. |
Plan migracji
Faza 1: Wewnętrzna domena wiadomości
- Dodaj typy
src/channels/message/*dla wiadomości, celów, relacji, źródeł, potwierdzeń, możliwości, trwałych intencji, kontekstu odbierania, kontekstu wysyłania, kontekstu live i klas awarii. - Dodaj
origin?: MessageOrigindo typu ładunku mostu migracyjnego używanego przez bieżące dostarczanie odpowiedzi, a następnie przenieś to pole doChannelMessagei renderowanych typów wiadomości, gdy refaktoryzacja zastąpi ładunki odpowiedzi. - Utrzymaj to jako wewnętrzne, dopóki adaptery i testy nie potwierdzą kształtu.
- Dodaj czyste testy jednostkowe dla przejść stanów i serializacji.
Faza 2: Rdzeń trwałego wysyłania
- Przenieś istniejącą kolejkę wychodzącą z trwałości ładunków odpowiedzi do trwałych intencji wysyłania wiadomości.
- Pozwól trwałej intencji wysyłania przenosić projektowaną tablicę ładunków lub plan partii, a nie tylko jeden ładunek odpowiedzi.
- Zachowaj obecne zachowanie odzyskiwania kolejki przez konwersję zgodności.
- Spraw, aby
deliverOutboundPayloadswywoływałomessages.send. - Uczyń trwałość wysyłania końcowego domyślną i zamykaj z błędem, gdy trwałej intencji nie da się zapisać w nowym cyklu życia wiadomości, po tym jak adapter zadeklaruje bezpieczeństwo odtwarzania. Istniejące ścieżki zgodności channel-turn i SDK pozostają domyślnie bezpośrednim wysyłaniem w tej fazie.
- Rejestruj potwierdzenia spójnie.
- Zwracaj potwierdzenia i wyniki dostarczania do pierwotnego wywołującego dyspozytor zamiast traktować trwałe wysyłanie jako końcowy efekt uboczny.
- Utrwalaj pochodzenie wiadomości przez trwałe intencje wysyłania, aby odzyskiwanie, odtwarzanie i wysyłanie w częściach zachowywały operacyjne pochodzenie OpenClaw.
Faza 3: Most obrotu kanału
- Zaimplementuj ponownie
channel.turn.runidispatchAssembledChannelTurnna baziemessages.receiveimessages.send. - Utrzymaj stabilność bieżących typów faktów.
- Domyślnie zachowaj dotychczasowe zachowanie. Kanał złożonego obrotu staje się trwały tylko wtedy, gdy jego adapter jawnie wybierze politykę trwałości bezpieczną dla odtwarzania.
- Zachowaj
durable: falsejako furtkę zgodności dla ścieżek, które finalizują natywne edycje i nie mogą jeszcze bezpiecznie odtwarzać, ale nie polegaj na znacznikachfalse, aby chronić niezmodernizowane kanały. - Domyślnie włącz trwałość złożonego obrotu tylko w nowym cyklu życia wiadomości, po tym jak mapowanie kanału potwierdzi, że ogólna ścieżka wysyłania zachowuje stare semantyki dostarczania kanału.
Faza 4: Most przygotowanego dyspozytora
- Zastąp
deliverDurableInboundReplyPayloadmostem kontekstu wysyłania. - Zachowaj stary helper jako wrapper.
- Najpierw przenieś Telegram, WhatsApp, Slack, Signal, iMessage i Discord, ponieważ mają już pracę nad trwałym finalnym wysyłaniem albo prostsze ścieżki wysyłania.
- Traktuj każdy przygotowany dispatcher jako nieobjęty pokryciem, dopóki wyraźnie nie zdecyduje się na kontekst wysyłania. Dokumentacja i wpisy changeloga muszą mówić „złożone przebiegi kanału” albo nazywać zmigrowane ścieżki kanałów, zamiast twierdzić, że obejmują wszystkie automatyczne odpowiedzi finalne.
- Zachowaj
recordInboundSessionAndDispatchReply, helpery bezpośrednich DM i podobne publiczne helpery zgodności w sposób zachowujący dotychczasowe zachowanie. Mogą później udostępnić jawne włączenie kontekstu wysyłania, ale nie mogą automatycznie próbować ogólnego trwałego dostarczania przed callbackiem dostarczania należącym do wywołującego.
Faza 5: Ujednolicony Cykl Życia Na Żywo
- Zbuduj
messages.livez dwoma adapterami dowodowymi:- Telegram dla wysyłania, edycji oraz wysyłania przedawnionego finalnego komunikatu.
- Matrix dla finalizacji wersji roboczej oraz zapasowej redakcji.
- Następnie zmigruj Discord, Slack, Mattermost, Teams, QQ Bot i Feishu.
- Usuń zduplikowany kod finalizacji podglądu dopiero wtedy, gdy każdy kanał będzie mieć testy parytetu.
Faza 6: Publiczny SDK
- Dodaj
openclaw/plugin-sdk/channel-message. - Udokumentuj go jako preferowane API Plugin kanału.
- Zaktualizuj eksporty pakietu, spis punktów wejścia, wygenerowane baseline API oraz dokumentację SDK pluginów.
- Uwzględnij
MessageOrigin, haki kodowania/dekodowania origin oraz współdzielony predykatshouldDropOpenClawEchow powierzchni SDK channel-message. - Zachowaj wrappery zgodności dla starych podścieżek.
- Oznacz helpery SDK nazwane od odpowiedzi jako przestarzałe w dokumentacji po migracji bundled pluginów.
Faza 7: Wszyscy Nadawcy
Przenieś wszystkich nadawców wychodzących niebędących odpowiedziami namessages.send:
- powiadomienia Cron i Heartbeat
- ukończenia zadań
- wyniki hooków
- prośby o zatwierdzenie i wyniki zatwierdzeń
- wysyłki narzędzia wiadomości
- ogłoszenia ukończenia subagenta
- jawne wysyłki CLI lub Control UI
- ścieżki automatyzacji/broadcastu
Faza 8: Wycofanie Turn
- Zachowaj
channel.turnjako wrapper przez co najmniej jedno okno zgodności. - Opublikuj notatki migracyjne.
- Uruchom testy zgodności SDK pluginów względem starych importów.
- Usuń albo ukryj stare wewnętrzne helpery dopiero wtedy, gdy żaden bundled plugin ich nie potrzebuje, a kontrakty zewnętrznych pluginów mają stabilny zamiennik.
Plan testów
Testy jednostkowe:- Serializacja i odzyskiwanie trwałej intencji wysyłania.
- Ponowne użycie klucza idempotencji i tłumienie duplikatów.
- Commit potwierdzenia i pominięcie odtworzenia.
- Odzyskiwanie
unknown_after_send, które uzgadnia stan przed odtworzeniem, gdy adapter obsługuje uzgadnianie. - Polityka klasyfikacji awarii.
- Sekwencjonowanie polityki potwierdzania odbioru.
- Mapowanie relacji dla odpowiedzi, kontynuacji, wysyłek systemowych i broadcastowych.
- Fabryka origin dla awarii Gateway oraz predykat
shouldDropOpenClawEcho. - Zachowanie origin przez normalizację payloadu, dzielenie na części, serializację trwałej kolejki i odzyskiwanie.
- Prosty adapter
channel.turn.runnadal rejestruje i wysyła. - Starsze dostarczanie złożonego przebiegu nie staje się trwałe, chyba że kanał wyraźnie się na to zdecyduje.
- Most
channel.turn.runPreparednadal rejestruje i finalizuje. - Publiczne helpery zgodności domyślnie wywołują callbacki dostarczania należące do wywołującego i nie wykonują ogólnego wysłania przed tymi callbackami.
- Trwałe dostarczanie zapasowe odtwarza całą przewidywaną tablicę payloadów po restarcie i nie może pozostawić późniejszych payloadów niezarejestrowanych po wczesnej awarii.
- Trwałe dostarczanie złożonego przebiegu zwraca identyfikatory wiadomości platformy do buforowanego dispatchera.
- Niestandardowe haki dostarczania nadal zwracają identyfikatory wiadomości platformy, gdy trwałe dostarczanie jest wyłączone lub niedostępne.
- Odpowiedź finalna przetrwa restart między ukończeniem asystenta a wysłaniem na platformę.
- Wersja robocza podglądu finalizuje się w miejscu, gdy jest to dozwolone.
- Wersja robocza podglądu jest anulowana albo zredagowana, gdy media/błąd/niezgodność celu odpowiedzi wymaga normalnego dostarczania.
- Strumieniowanie bloków i strumieniowanie podglądu nie dostarczają tego samego tekstu jednocześnie.
- Media przesłane strumieniowo wcześnie nie są duplikowane w finalnym dostarczaniu.
- Odpowiedź tematu Telegram z opóźnionym potwierdzeniem pollingu do bezpiecznego ukończonego znacznika wodnego kontekstu odbioru.
- Odzyskiwanie pollingu Telegram dla zaakceptowanych, ale niedostarczonych aktualizacji objęte utrwalonym modelem bezpiecznego ukończonego offsetu.
- Przedawniony podgląd Telegram wysyła świeży finalny komunikat i czyści podgląd.
- Cicha ścieżka zapasowa Telegram wysyła każdy przewidywany payload zapasowy.
- Trwałość cichej ścieżki zapasowej Telegram rejestruje pełną przewidywaną tablicę zapasową atomowo, a nie jedną trwałą intencję z pojedynczym payloadem na iterację pętli.
- Discord anuluje podgląd przy mediach/błędzie/jawnej odpowiedzi.
- Finalne komunikaty przygotowanego dispatchera Discord przechodzą przez kontekst wysyłania, zanim dokumentacja lub changelog ogłosi trwałość finalnych odpowiedzi Discord.
- Trwałe finalne wysyłki iMessage zasilają cache echa wysłanych wiadomości monitora.
- Starsze ścieżki dostarczania LINE, BlueBubbles, Zalo i Nostr nie są omijane przez ogólne trwałe wysyłanie, dopóki nie istnieją testy parytetu ich adapterów.
- Dostarczanie callbackiem Direct-DM/Nostr pozostaje autorytatywne, chyba że zostanie wyraźnie zmigrowane do kompletnego celu wiadomości i odpornego na odtwarzanie adaptera wysyłania.
- Otagowane komunikaty awarii Slack OpenClaw Gateway pozostają widoczne wychodząco, otagowane
echa pokoju bota są odrzucane przed
allowBots, a nieotagowane wiadomości bota z tym samym widocznym tekstem nadal przechodzą normalną autoryzację botów. - Natywna zapasowa ścieżka strumienia Slack do wersji roboczej podglądu w DM najwyższego poziomu.
- Finalizacja podglądu Matrix i zapasowa redakcja.
- Otagowane echa pokojowe awarii OpenClaw Gateway w Matrix z skonfigurowanych kont botów
są odrzucane przed obsługą
allowBots. - Audyty kaskady awarii Gateway w pokojach współdzielonych Discord i Google Chat obejmują
tryby
allowBotsprzed deklarowaniem ogólnej ochrony w tych miejscach. - Finalizacja wersji roboczej Mattermost i zapasowe świeże wysłanie.
- Finalizacja natywnego postępu Teams.
- Feishu tłumi zduplikowany finalny komunikat.
- Zapasowa ścieżka timeoutu akumulatora QQ Bot.
- Trwałe finalne wysyłki Tlon zachowują renderowanie sygnatury modelu i śledzenie uczestniczących wątków.
- Proste trwałe finalne wysyłki WhatsApp, Signal, iMessage, Google Chat, LINE, IRC, Nostr, Nextcloud Talk, Synology Chat, Tlon, Twitch, Zalo i Zalo Personal.
- Docelowe pliki Vitest podczas rozwoju.
pnpm check:changedw Testbox dla pełnej zmienionej powierzchni.- Szersze
pnpm checkw Testbox przed landowaniem kompletnego refaktoru albo po zmianach publicznego SDK/eksportów. - Smoke live albo qa-channel dla co najmniej jednego kanału obsługującego edycję i jednego prostego kanału tylko do wysyłania przed usunięciem wrapperów zgodności.
Otwarte pytania
- Czy Telegram powinien docelowo zastąpić źródło runnera grammY w pełni trwałym źródłem pollingu, które może kontrolować ponowne dostarczanie na poziomie platformy, a nie tylko utrwalony znacznik wodny restartu OpenClaw.
- Czy trwały stan podglądu live powinien być przechowywany w tym samym rekordzie kolejki co finalna intencja wysyłania, czy w sąsiednim magazynie stanu live.
- Jak długo wrappery zgodności pozostają udokumentowane po wydaniu
plugin-sdk/channel-message. - Czy zewnętrzne pluginy powinny implementować adaptery odbioru bezpośrednio, czy tylko
dostarczać haki normalize/send/live przez
defineChannelMessageAdapter. - Które pola potwierdzeń można bezpiecznie udostępnić w publicznym SDK względem wewnętrznego stanu runtime.
- Czy efekty uboczne, takie jak cache self-echo i znaczniki uczestniczących wątków, powinny być modelowane jako haki kontekstu wysyłania, kroki finalizacji należące do adaptera albo subskrybenci potwierdzeń.
- Które kanały mają natywne metadane origin, które potrzebują utrwalonych rejestrów wychodzących, a które nie mogą zaoferować niezawodnego tłumienia echa między botami.
Kryteria akceptacji
- Każdy bundled kanał wiadomości wysyła finalne widoczne wyjście przez
messages.send. - Każdy przychodzący kanał wiadomości wchodzi przez
messages.receivealbo udokumentowany wrapper zgodności. - Każdy kanał podglądu/edycji/strumienia używa
messages.livedla stanu wersji roboczej i finalizacji. channel.turnjest tylko wrapperem.- Helpery SDK nazwane od odpowiedzi są eksportami zgodności, a nie zalecaną ścieżką.
- Trwałe odzyskiwanie może odtworzyć oczekujące finalne wysyłki po restarcie bez utraty finalnej odpowiedzi ani duplikowania już zatwierdzonych wysyłek; wysyłki, których wynik platformy jest nieznany, są uzgadniane przed odtworzeniem albo udokumentowane jako co najmniej jednokrotne dla danego adaptera.
- Trwałe finalne wysyłki zamykają się bezpiecznie przy awarii, gdy trwała intencja nie może zostać zapisana, chyba że wywołujący wyraźnie wybrał udokumentowany tryb nietrwały.
- Starsze helpery channel-turn i zgodności SDK domyślnie używają bezpośredniego dostarczania należącego do kanału; ogólne trwałe wysyłanie jest tylko jawnym włączeniem.
- Potwierdzenia zachowują wszystkie identyfikatory wiadomości platformy dla dostarczeń wieloczęściowych oraz identyfikator główny dla wygody wątkowania/edycji.
- Trwałe wrappery zachowują lokalne dla kanału efekty uboczne przed zastąpieniem bezpośrednich callbacków dostarczania.
- Przygotowane dispatchery nie są liczone jako trwałe, dopóki ich finalna ścieżka dostarczania wyraźnie nie używa kontekstu wysyłania.
- Dostarczanie zapasowe obsługuje każdy przewidywany payload.
- Trwałe dostarczanie zapasowe rejestruje każdy przewidywany payload w jednej odtwarzalnej intencji albo planie batcha.
- Wyjście awarii Gateway pochodzące z OpenClaw jest widoczne dla ludzi, ale otagowane echa pokojowe autorstwa bota są odrzucane przed autoryzacją bota na kanałach, które deklarują obsługę kontraktu origin.
- Dokumentacja wyjaśnia wysyłanie, odbiór, live, stan, potwierdzenia, relacje, politykę awarii, migrację i pokrycie testami.