Skip to content

Commit c33e578

Browse files
authored
feat: add channel progress drafts
Adds unified progress-draft streaming for chat channels, with docs and per-channel regressions.
1 parent 5355ef0 commit c33e578

43 files changed

Lines changed: 1861 additions & 209 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ Docs: https://docs.openclaw.ai
1010

1111
### Changes
1212

13+
- Channels/streaming: add unified `streaming.mode: "progress"` drafts with auto single-word status labels and shared progress configuration across Discord, Telegram, Matrix, Slack, and Microsoft Teams.
1314
- Tools/BTW: add `/side` as a text and native slash-command alias for `/btw` side questions.
1415
- Agents/tools: skip optional media and PDF tool factories when the effective tool denylist already blocks them, avoiding unnecessary hot-path setup for tools that will be filtered out before model use. (#76773) Thanks @dorukardahan.
1516
- Discord/status: let explicit reaction tool calls opt into tracking subsequent tool progress on the reacted message with `trackToolCalls: true`, and use the shared tool display emoji table for status reactions.
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
b3d5eb9ae0e53dfd8bd8e2b06373fd80b84db1057fe88075afc4b890ff179371 config-baseline.json
1+
c165172059698df0d806ee9861b9ba1433c2055935bbf81497437897bfcc4e6f config-baseline.json
22
bfb7ade43e58c630d0480eaa215ef22bf0d5030136c3e24cdd2c2a4c73d1b663 config-baseline.core.json
3-
09a952cf734a5b4a30f760e570c0f106d54aa8e74bf439dd4d07013f9f7607e4 config-baseline.channel.json
3+
f0e77e90432c987c27143194f70df649bac7595e78613b3708366ff32401369f config-baseline.channel.json
44
055fae0d0067a751dc10125af7421da45633f73519c94c982d02b0c4eb2bdf67 config-baseline.plugin.json

docs/.i18n/glossary.zh-CN.json

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,42 @@
287287
"source": "Block streaming",
288288
"target": "分块流式传输"
289289
},
290+
{
291+
"source": "Progress drafts",
292+
"target": "进度草稿"
293+
},
294+
{
295+
"source": "Streaming and chunking",
296+
"target": "流式传输和分块"
297+
},
298+
{
299+
"source": "Messages",
300+
"target": "消息"
301+
},
302+
{
303+
"source": "Channel configuration",
304+
"target": "频道配置"
305+
},
306+
{
307+
"source": "Discord",
308+
"target": "Discord"
309+
},
310+
{
311+
"source": "Matrix",
312+
"target": "Matrix"
313+
},
314+
{
315+
"source": "Microsoft Teams",
316+
"target": "Microsoft Teams"
317+
},
318+
{
319+
"source": "Slack",
320+
"target": "Slack"
321+
},
322+
{
323+
"source": "Telegram",
324+
"target": "Telegram"
325+
},
290326
{
291327
"source": "Discovery + transports",
292328
"target": "设备发现 + 传输协议"

docs/channels/discord.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -660,7 +660,7 @@ Default slash command settings:
660660
</Accordion>
661661

662662
<Accordion title="Live stream preview">
663-
OpenClaw can stream draft replies by sending a temporary message and editing it as text arrives. `channels.discord.streaming` takes `off` (default) | `partial` | `block` | `progress`. `progress` maps to `partial` on Discord; `streamMode` is a legacy alias and is auto-migrated.
663+
OpenClaw can stream draft replies by sending a temporary message and editing it as text arrives. `channels.discord.streaming` takes `off` (default) | `partial` | `block` | `progress`. `progress` keeps one editable status draft and updates it with tool progress until final delivery; `streamMode` is a legacy alias and is auto-migrated.
664664

665665
Default stays `off` because Discord preview edits hit rate limits quickly when multiple bots or gateways share an account.
666666

docs/channels/telegram.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -278,11 +278,11 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
278278
Requirement:
279279

280280
- `channels.telegram.streaming` is `off | partial | block | progress` (default: `partial`)
281-
- `progress` maps to `partial` on Telegram (compat with cross-channel naming)
281+
- `progress` keeps one editable status draft and updates it with tool progress until final delivery
282282
- `streaming.preview.toolProgress` controls whether tool/progress updates reuse the same edited preview message (default: `true` when preview streaming is active)
283283
- legacy `channels.telegram.streamMode` and boolean `streaming` values are detected; run `openclaw doctor --fix` to migrate them to `channels.telegram.streaming.mode`
284284

285-
Tool-progress preview updates are the short "Working..." lines shown while tools run, for example command execution, file reads, planning updates, or patch summaries. Telegram keeps these enabled by default to match released OpenClaw behavior from `v2026.4.22` and later. To keep the edited preview for answer text but hide tool-progress lines, set:
285+
Tool-progress preview updates are the short status lines shown while tools run, for example command execution, file reads, planning updates, or patch summaries. Telegram keeps these enabled by default to match released OpenClaw behavior from `v2026.4.22` and later. To keep the edited preview for answer text but hide tool-progress lines, set:
286286

287287
```json
288288
{
@@ -299,10 +299,10 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
299299
}
300300
```
301301

302-
Use `streaming.mode: "off"` only when you want final-only delivery: Telegram preview edits are disabled and generic tool/progress chatter is suppressed instead of being sent as standalone "Working..." messages. Approval prompts, media payloads, and errors still route through normal final delivery. Use `streaming.preview.toolProgress: false` when you only want to keep answer preview edits while hiding the tool-progress status lines.
302+
Use `streaming.mode: "off"` only when you want final-only delivery: Telegram preview edits are disabled and generic tool/progress chatter is suppressed instead of being sent as standalone status messages. Approval prompts, media payloads, and errors still route through normal final delivery. Use `streaming.preview.toolProgress: false` when you only want to keep answer preview edits while hiding the tool-progress status lines.
303303

304304
<Note>
305-
Telegram selected quote replies are the exception. When `replyToMode` is `"first"`, `"all"`, or `"batched"` and the inbound message includes selected quote text, OpenClaw sends the final answer through Telegram's native quote-reply path instead of editing the answer preview, so `streaming.preview.toolProgress` cannot show the short "Working..." lines for that turn. Current-message replies without selected quote text still keep preview streaming. Set `replyToMode: "off"` when tool-progress visibility matters more than native quote replies, or set `streaming.preview.toolProgress: false` to acknowledge the trade-off.
305+
Telegram selected quote replies are the exception. When `replyToMode` is `"first"`, `"all"`, or `"batched"` and the inbound message includes selected quote text, OpenClaw sends the final answer through Telegram's native quote-reply path instead of editing the answer preview, so `streaming.preview.toolProgress` cannot show the short status lines for that turn. Current-message replies without selected quote text still keep preview streaming. Set `replyToMode: "off"` when tool-progress visibility matters more than native quote replies, or set `streaming.preview.toolProgress: false` to acknowledge the trade-off.
306306
</Note>
307307

308308
For text-only replies:

docs/concepts/progress-drafts.md

Lines changed: 284 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,284 @@
1+
---
2+
summary: "Progress drafts: one visible work-in-progress message that updates while an agent runs"
3+
read_when:
4+
- Configuring visible progress updates for long-running chat turns
5+
- Choosing between partial, block, and progress streaming modes
6+
- Explaining how OpenClaw updates one channel message while work is in progress
7+
- Troubleshooting progress drafts, standalone progress messages, or finalization fallback
8+
title: "Progress drafts"
9+
---
10+
11+
Progress drafts make long-running agent turns feel alive in chat without turning
12+
the conversation into a stack of temporary status replies.
13+
14+
When progress drafts are enabled, OpenClaw creates one visible work-in-progress
15+
message, updates it while the agent reads, plans, calls tools, or waits for
16+
approval, and then turns that draft into the final answer when the channel can
17+
do that safely.
18+
19+
```text
20+
Shelling
21+
- reading recent channel context
22+
- checking matching issues
23+
- preparing reply
24+
```
25+
26+
Use progress drafts when you want one tidy status message during tool-heavy work
27+
and the final answer when the turn is done.
28+
29+
## Quick Start
30+
31+
Enable progress drafts per channel with `streaming.mode: "progress"`:
32+
33+
```json5
34+
{
35+
channels: {
36+
discord: {
37+
streaming: {
38+
mode: "progress",
39+
},
40+
},
41+
},
42+
}
43+
```
44+
45+
That is usually enough. OpenClaw will pick an automatic one-word label, add
46+
compact progress lines while useful work happens, and suppress duplicate
47+
standalone progress chatter for that turn.
48+
49+
## What Users See
50+
51+
A progress draft has two parts:
52+
53+
| Part | Purpose |
54+
| -------------- | ----------------------------------------------------------------- |
55+
| Label | A short title such as `Thinking` or `Shelling`. |
56+
| Progress lines | Compact run updates such as tool calls, task steps, or approvals. |
57+
58+
The label appears immediately when the agent starts replying. Progress lines are
59+
added only when the agent emits useful work updates. The final answer replaces
60+
the draft when possible; otherwise OpenClaw sends the final answer normally and
61+
cleans up or stops updating the draft according to the channel's transport.
62+
63+
## Choose A Mode
64+
65+
`channels.<channel>.streaming.mode` controls the visible in-progress behavior:
66+
67+
| Mode | Best for | What appears in chat |
68+
| ---------- | -------------------------------- | ------------------------------------------------- |
69+
| `off` | Quiet channels | Only the final answer. |
70+
| `partial` | Watching answer text appear | One draft edited with the latest answer text. |
71+
| `block` | Larger answer-preview chunks | One preview updated or appended in bigger chunks. |
72+
| `progress` | Tool-heavy or long-running turns | One status draft, then the final answer. |
73+
74+
Choose `progress` when users care more about "what is happening" than watching
75+
the answer text stream token by token.
76+
77+
Choose `partial` when the answer itself is the progress signal.
78+
79+
Choose `block` when you want draft preview updates in larger text chunks. On
80+
Discord and Telegram, `streaming.mode: "block"` is still preview streaming, not
81+
normal block delivery. Use `streaming.block.enabled` or legacy
82+
`blockStreaming` when you want normal block replies.
83+
84+
## Configure Labels
85+
86+
Progress labels live under `channels.<channel>.streaming.progress`.
87+
88+
The default label is `auto`, which chooses from OpenClaw's built-in single-word
89+
label pool:
90+
91+
```text
92+
Thinking
93+
Shelling
94+
Scuttling
95+
Clawing
96+
Pinching
97+
Molting
98+
Bubbling
99+
Tiding
100+
Reefing
101+
Cracking
102+
Sifting
103+
Brining
104+
Nautiling
105+
Krilling
106+
Barnacling
107+
Lobstering
108+
Tidepooling
109+
Pearling
110+
Snapping
111+
Surfacing
112+
```
113+
114+
Use a fixed label:
115+
116+
```json5
117+
{
118+
channels: {
119+
discord: {
120+
streaming: {
121+
mode: "progress",
122+
progress: {
123+
label: "Investigating",
124+
},
125+
},
126+
},
127+
},
128+
}
129+
```
130+
131+
Use your own automatic label pool:
132+
133+
```json5
134+
{
135+
channels: {
136+
discord: {
137+
streaming: {
138+
mode: "progress",
139+
progress: {
140+
label: "auto",
141+
labels: ["Checking", "Reading", "Testing", "Finishing"],
142+
},
143+
},
144+
},
145+
},
146+
}
147+
```
148+
149+
Hide the label and show only progress lines:
150+
151+
```json5
152+
{
153+
channels: {
154+
discord: {
155+
streaming: {
156+
mode: "progress",
157+
progress: {
158+
label: false,
159+
},
160+
},
161+
},
162+
},
163+
}
164+
```
165+
166+
## Control Progress Lines
167+
168+
Progress lines are enabled by default in progress mode. They come from real run
169+
events: tool starts, item updates, task plans, approvals, command output, patch
170+
summaries, and similar agent activity.
171+
172+
Limit how many lines stay visible:
173+
174+
```json5
175+
{
176+
channels: {
177+
discord: {
178+
streaming: {
179+
mode: "progress",
180+
progress: {
181+
maxLines: 4,
182+
},
183+
},
184+
},
185+
},
186+
}
187+
```
188+
189+
Keep the single progress draft but hide tool and task lines:
190+
191+
```json5
192+
{
193+
channels: {
194+
discord: {
195+
streaming: {
196+
mode: "progress",
197+
progress: {
198+
toolProgress: false,
199+
},
200+
},
201+
},
202+
},
203+
}
204+
```
205+
206+
With `toolProgress: false`, OpenClaw still suppresses the older standalone
207+
tool-progress messages for that turn. The channel stays visually quiet until the
208+
final answer, except for the label if one is configured.
209+
210+
## Channel Behavior
211+
212+
Each channel uses the cleanest transport it supports:
213+
214+
| Channel | Progress transport | Notes |
215+
| --------------- | -------------------------------------- | --------------------------------------------------------------------- |
216+
| Discord | Send one message, then edit it. | Final text edits in place when it fits one safe preview message. |
217+
| Matrix | Send one event, then edit it. | Account-level streaming config controls account-level drafts. |
218+
| Microsoft Teams | Native Teams stream in personal chats. | `streaming.mode: "block"` maps to Teams block delivery. |
219+
| Slack | Native stream or editable draft post. | Thread availability affects whether native streaming can be used. |
220+
| Telegram | Send one message, then edit it. | Older visible drafts may be replaced so final timestamps stay useful. |
221+
| Mattermost | Editable draft post. | Tool activity is folded into the same draft-style post. |
222+
223+
Channels without safe edit support usually fall back to typing indicators or
224+
final-only delivery.
225+
226+
## Finalization
227+
228+
When the final answer is ready, OpenClaw tries to keep the chat clean:
229+
230+
- If the draft can safely become the final answer, OpenClaw edits it in place.
231+
- If the channel uses native progress streaming, OpenClaw finalizes that stream
232+
when the native transport accepts the final text.
233+
- If the final answer has media, an approval prompt, an explicit reply target,
234+
too many chunks, or a failed edit/send, OpenClaw sends the final answer through
235+
the normal channel delivery path.
236+
237+
The fallback path is intentional. It is better to send a fresh final answer than
238+
to lose text, mis-thread a reply, or overwrite a draft with a payload the channel
239+
cannot represent safely.
240+
241+
## Troubleshooting
242+
243+
**I only see the final answer.**
244+
245+
Check that `channels.<channel>.streaming.mode` is set to `progress` for the
246+
account or channel that handled the message. Some group or quote-reply paths may
247+
disable draft previews for a turn when the channel cannot safely edit the right
248+
message.
249+
250+
**I see the label but no tool lines.**
251+
252+
Check `streaming.progress.toolProgress`. If it is `false`, OpenClaw keeps the
253+
single draft behavior but hides tool and task progress lines.
254+
255+
**I see a fresh final message instead of an edited draft.**
256+
257+
That is a safety fallback. It can happen for media replies, long answers,
258+
explicit reply targets, old Telegram drafts, missing Slack thread targets,
259+
deleted preview messages, or failed native stream finalization.
260+
261+
**I still see standalone progress messages.**
262+
263+
Progress mode suppresses default standalone tool-progress messages when a draft
264+
is active. If standalone messages still appear, verify that the turn is actually
265+
using progress mode and not `streaming.mode: "off"` or a channel path that
266+
cannot create a draft for that message.
267+
268+
**Teams behaves differently from Discord or Telegram.**
269+
270+
Microsoft Teams uses a native stream in personal chats instead of the generic
271+
send-and-edit preview transport. Teams also treats `streaming.mode: "block"` as
272+
Teams block delivery because it does not have the same draft-preview block mode
273+
used by Discord and Telegram.
274+
275+
## Related
276+
277+
- [Streaming and chunking](/concepts/streaming)
278+
- [Messages](/concepts/messages)
279+
- [Channel configuration](/gateway/config-channels)
280+
- [Discord](/channels/discord)
281+
- [Matrix](/channels/matrix)
282+
- [Microsoft Teams](/channels/msteams)
283+
- [Slack](/channels/slack)
284+
- [Telegram](/channels/telegram)

0 commit comments

Comments
 (0)