





















@@ -2,12 +2,12 @@
22summary: "Design plan for the unified durable message receive, send, preview, edit, and streaming lifecycle"
33read_when:
44 - Refactoring channel send or receive behavior
5- - Changing channel turn, reply dispatch, outbound queue, preview streaming, or plugin SDK message APIs
5+ - Changing channel inbound, reply dispatch, outbound queue, preview streaming, or plugin SDK message APIs
66 - Designing a new channel plugin that needs durable sends, receipts, previews, edits, or retries
77title: "Message lifecycle refactor"
88---
9910-This page is the target design for replacing scattered channel turn, reply
10+This page is the target design for replacing scattered channel inbound, reply
1111dispatch, preview streaming, and outbound delivery helpers with one durable
1212message lifecycle.
1313@@ -20,14 +20,14 @@ The short version:
2020 commit, fail.
2121- Receiving must be context based too: normalize, dedupe, route, record,
2222 dispatch, platform ack, fail.
23-- The public plugin SDK should collapse to one small channel-message surface.
23+- The public plugin SDK should collapse to one small channel-outbound surface.
24242525## Problems
26262727The current channel stack grew from several valid local needs:
282829-- Simple inbound adapters use `runtime.channel.turn.run`.
30-- Rich adapters use `runtime.channel.turn.runPrepared`.
29+- Simple inbound adapters use `runtime.channel.inbound.run`.
30+- Rich adapters use `runtime.channel.inbound.runPreparedReply`.
3131- Legacy helpers use `dispatchInboundReplyWithBase`,
3232`recordInboundSessionAndDispatchReply`, reply payload helpers, reply chunking,
3333 reply references, and outbound runtime helpers.
@@ -67,7 +67,7 @@ non-durable policy.
6767- Shared preview, edit, stream, finalization, retry, recovery, and receipt
6868 semantics.
6969- A small plugin SDK surface that third-party plugins can learn and maintain.
70-- Compatibility for existing `channel.turn` callers during migration.
70+- Compatibility for existing inbound reply compatibility callers during migration.
7171- Clear extension points for new channel capabilities.
7272- No platform-specific branches in core.
7373- No token-delta channel messages. Channel streaming remains message preview,
@@ -77,7 +77,7 @@ non-durable policy.
77777878## Non goals
797980-- Do not remove `runtime.channel.turn.*` in the first phase.
80+- Do not force every existing channel onto durable message delivery in the first phase.
8181- Do not force every channel into the same native transport behavior.
8282- Do not teach core Telegram topics, Slack native streams, Matrix redactions,
8383 Feishu cards, QQ voice, or Teams activities.
@@ -557,7 +557,7 @@ This should cover current behavior:
557557The public SDK target should be one subpath:
558558559559```typescript
560-import { defineChannelMessageAdapter } from "openclaw/plugin-sdk/channel-message";
560+import { defineChannelMessageAdapter } from "openclaw/plugin-sdk/channel-outbound";
561561```
562562563563Target shape:
@@ -670,22 +670,22 @@ should not need them.
670670671671Bundled plugins may keep internal helper imports through reserved runtime
672672subpaths while migrating. Public docs should steer plugin authors to
673-`plugin-sdk/channel-message` once it exists.
673+`plugin-sdk/channel-outbound` once it exists.
674674675-## Relationship to channel turn
675+## Relationship to channel inbound
676676677-`runtime.channel.turn.*` should stay during migration.
677+`runtime.channel.inbound.*` is the runtime bridge during migration.
678678679679It should become a compatibility adapter:
680680681681```text
682-channel.turn.run
682+channel.inbound.run
683683 -> messages.receive context
684684 -> session dispatch
685685 -> messages.send context for visible output
686686```
687687688-`channel.turn.runPrepared` should also remain initially:
688+`channel.inbound.runPreparedReply` should also remain initially:
689689690690```text
691691channel-owned dispatcher
@@ -694,10 +694,8 @@ channel-owned dispatcher
694694 -> messages.send for final delivery
695695```
696696697-After all bundled plugins and known third-party compatibility paths are bridged,
698-`channel.turn` can be deprecated. It should not be removed until there is a
699-published SDK migration path and contract tests proving old plugins still work
700-or fail with a clear version error.
697+The old `channel.turn` runtime surface remains a deprecated alias only. New code
698+uses inbound/message nouns.
701699702700## Compatibility guardrails
703701@@ -706,10 +704,10 @@ existing delivery callback has side effects beyond "send this payload".
706704707705Legacy entry points are non-durable by default:
708706709-- `channel.turn.run` and `dispatchAssembledChannelTurn` use the channel's
707+- `channel.inbound.run` and `dispatchChannelInboundReply` use the channel's
710708 delivery callback unless that channel explicitly supplies an audited durable
711709 policy/options object.
712-- `channel.turn.runPrepared` stays channel-owned until the prepared dispatcher
710+- `channel.inbound.runPreparedReply` stays channel-owned until the prepared dispatcher
713711 explicitly calls the send context.
714712- Public compatibility helpers such as `recordInboundSessionAndDispatchReply`,
715713`dispatchInboundReplyWithBase`, and direct-DM helpers never inject generic
@@ -902,17 +900,17 @@ Core policy:
902900- Make `deliverOutboundPayloads` call `messages.send`.
903901- Make final-send durability the default and fail closed when the durable intent
904902 cannot be written in the new message lifecycle, after the adapter declares
905- replay safety. Existing channel-turn and SDK compatibility paths remain
903+ replay safety. Existing inbound runner and SDK compatibility paths remain
906904 direct-send by default during this phase.
907905- Record receipts consistently.
908906- Return receipts and delivery results to the original dispatcher caller instead
909907 of treating durable send as a terminal side effect.
910908- Persist message origin through durable send intents so recovery, replay, and
911909 chunked sends preserve OpenClaw operational provenance.
912910913-### Phase 3: Channel Turn Bridge
911+### Phase 3: Channel Inbound Bridge
914912915-- Reimplement `channel.turn.run` and `dispatchAssembledChannelTurn` on top of
913+- Reimplement `channel.inbound.run` and `dispatchChannelInboundReply` on top of
916914`messages.receive` and `messages.send`.
917915- Keep current fact types stable.
918916- Keep legacy behavior by default. An assembled-turn channel becomes durable
@@ -950,12 +948,12 @@ Core policy:
950948951949### Phase 6: Public SDK
952950953-- Add `openclaw/plugin-sdk/channel-message`.
951+- Add `openclaw/plugin-sdk/channel-outbound`.
954952- Document it as the preferred channel plugin API.
955953- Update package exports, entrypoint inventory, generated API baselines, and
956954 plugin SDK docs.
957955- Include `MessageOrigin`, origin encode/decode hooks, and the shared
958-`shouldDropOpenClawEcho` predicate in the channel-message SDK surface.
956+`shouldDropOpenClawEcho` predicate in the channel-outbound SDK surface.
959957- Keep compatibility wrappers for old subpaths.
960958- Mark reply-named SDK helpers as deprecated in docs after bundled plugins are
961959 migrated.
@@ -976,9 +974,9 @@ Move all non-reply outbound producers onto `messages.send`:
976974This is where the model stops being "agent replies" and becomes "OpenClaw sends
977975messages".
978976979-### Phase 8: Deprecate Turn
977+### Phase 8: Remove Turn-Named Compatibility
980978981-- Keep `channel.turn` as a wrapper for at least one compatibility window.
979+- Keep inbound/message-named wrappers as the compatibility window.
982980- Publish migration notes.
983981- Run plugin SDK compatibility tests against old imports.
984982- Remove or hide old internal helpers only after no bundled plugin needs them
@@ -1002,10 +1000,10 @@ Unit tests:
1002100010031001Integration tests:
100410021005-- `channel.turn.run` simple adapter still records and sends.
1003+- `channel.inbound.run` simple adapter still records and sends.
10061004- Legacy assembled-event delivery does not become durable unless the channel
10071005 explicitly opts in.
1008-- `channel.turn.runPrepared` bridge still records and finalizes.
1006+- `channel.inbound.runPreparedReply` bridge still records and finalizes.
10091007- Public compatibility helpers call caller-owned delivery callbacks by default
10101008 and do not generic-send before those callbacks.
10111009- Durable fallback delivery replays the whole projected payload array after
@@ -1075,7 +1073,7 @@ Validation:
10751073- Whether durable live preview state should be stored in the same queue record
10761074 as the final send intent or in a sibling live-state store.
10771075- How long compatibility wrappers stay documented after
1078-`plugin-sdk/channel-message` ships.
1076+`plugin-sdk/channel-outbound` ships.
10791077- Whether third-party plugins should implement receive adapters directly or only
10801078 provide normalize/send/live hooks through `defineChannelMessageAdapter`.
10811079- Which receipt fields are safe to expose in public SDK versus internal runtime
@@ -1094,15 +1092,15 @@ Validation:
10941092 documented compatibility wrapper.
10951093- Every preview/edit/stream channel uses `messages.live` for draft state and
10961094 finalization.
1097-- `channel.turn` is only a wrapper.
1095+- `channel.inbound` is only a wrapper.
10981096- Reply-named SDK helpers are compatibility exports, not the recommended path.
10991097- Durable recovery can replay pending final sends after restart without losing
11001098 the final response or duplicating already committed sends; sends whose
11011099 platform outcome is unknown are reconciled before replay or documented as
11021100 at-least-once for that adapter.
11031101- Durable final sends fail closed when the durable intent cannot be written,
11041102 unless a caller explicitly selected a documented non-durable mode.
1105-- Legacy channel-turn and SDK compatibility helpers default to direct
1103+- Legacy SDK compatibility helpers default to direct
11061104 channel-owned delivery; generic durable send is explicit opt-in only.
11071105- Receipts preserve all platform message ids for multi-part deliveries and a
11081106 primary id for threading/edit convenience.
@@ -1125,4 +1123,4 @@ Validation:
11251123- [Streaming and chunking](/concepts/streaming)
11261124- [Progress drafts](/concepts/progress-drafts)
11271125- [Retry policy](/concepts/retry)
1128-- [Channel turn kernel](/plugins/sdk-channel-turn)
1126+- [Channel inbound API](/plugins/sdk-channel-inbound)
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。