mirror of
https://github.com/openclaw/openclaw.git
synced 2026-07-21 02:06:43 +00:00
fix(channels): keep markup out of the status label and make the line opt-in
Reasoning and commentary lines arrive channel-formatted, so falling back to their raw text leaked <i> markup into the status label; only structured work lines carry a clean label/detail pair. Defaulting the line to off keeps existing progress drafts byte-identical until a channel opts in.
This commit is contained in:
@@ -173,9 +173,9 @@ Configure with `channels.<channel>.streaming.progress.status`:
|
||||
|
||||
| Mode | Behavior |
|
||||
| ---------- | -------------------------------------------------------------- |
|
||||
| `activity` | Names the current work, e.g. `▸ Exec: run tests` (default) |
|
||||
| `minimal` | Static `▸ Working` label, still with elapsed time |
|
||||
| `off` | No status line |
|
||||
| `off` | No status line (default) |
|
||||
| `activity` | Names the current work, e.g. `▸ Exec: run tests` |
|
||||
| `minimal` | Static `▸ Working` label, still with elapsed time |
|
||||
|
||||
```json5
|
||||
{
|
||||
@@ -184,7 +184,7 @@ Configure with `channels.<channel>.streaming.progress.status`:
|
||||
streaming: {
|
||||
mode: "progress",
|
||||
progress: {
|
||||
status: "minimal",
|
||||
status: "activity",
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -192,6 +192,11 @@ Configure with `channels.<channel>.streaming.progress.status`:
|
||||
}
|
||||
```
|
||||
|
||||
The line is off by default: progress drafts already name the current work, so the status
|
||||
line mainly adds elapsed time and the steer hint, and enabling it changes what every
|
||||
draft in that channel looks like. Turn it on per channel when a turn's duration matters
|
||||
more than draft compactness.
|
||||
|
||||
Because the line is part of the progress draft, it appears only when that channel runs
|
||||
`streaming.mode: "progress"`. It is transport-only: it never enters the session
|
||||
transcript or the model context.
|
||||
|
||||
@@ -244,14 +244,14 @@ export function createChannelProgressDraftCompositor(params: {
|
||||
};
|
||||
|
||||
const resolveActivityLabel = (): string | undefined => {
|
||||
const newest = lines.at(-1);
|
||||
if (!newest) {
|
||||
// Only structured work lines carry a clean label/detail pair. String lines are
|
||||
// already channel-formatted (reasoning and commentary arrive with markup), so using
|
||||
// their text would leak `<i>` and friends into the status line.
|
||||
const newest = lines.findLast((line) => typeof line !== "string");
|
||||
if (!newest || typeof newest === "string" || !newest.label) {
|
||||
return undefined;
|
||||
}
|
||||
if (typeof newest === "string") {
|
||||
return newest;
|
||||
}
|
||||
return newest.detail ? `${newest.label}: ${newest.detail}` : newest.label || newest.text;
|
||||
return newest.detail ? `${newest.label}: ${newest.detail}` : newest.label;
|
||||
};
|
||||
|
||||
const resolveStatusLine = (): string | undefined => {
|
||||
|
||||
@@ -181,11 +181,11 @@ describe("streaming config resolution", () => {
|
||||
});
|
||||
|
||||
describe("progress draft status mode", () => {
|
||||
it("defaults to activity", () => {
|
||||
expect(resolveChannelProgressDraftStatusMode(undefined)).toBe("activity");
|
||||
expect(
|
||||
resolveChannelProgressDraftStatusMode({ streaming: { mode: "progress" } } as never),
|
||||
).toBe("activity");
|
||||
it("stays off until a channel opts in", () => {
|
||||
expect(resolveChannelProgressDraftStatusMode(undefined)).toBe("off");
|
||||
expect(resolveChannelProgressDraftStatusMode({ streaming: { mode: "progress" } } as never)).toBe(
|
||||
"off",
|
||||
);
|
||||
});
|
||||
|
||||
it("honors an explicit per-channel mode", () => {
|
||||
@@ -203,7 +203,7 @@ describe("progress draft status mode", () => {
|
||||
resolveChannelProgressDraftStatusMode({
|
||||
streaming: { mode: "progress", progress: { status: "loud" } },
|
||||
} as never),
|
||||
).toBe("activity");
|
||||
).toBe("off");
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -923,7 +923,7 @@ export function resolveChannelProgressDraftMaxLines(
|
||||
|
||||
export function resolveChannelProgressDraftStatusMode(
|
||||
entry: StreamingCompatEntry | null | undefined,
|
||||
defaultValue: StatusFooterMode = "activity",
|
||||
defaultValue: StatusFooterMode = "off",
|
||||
): StatusFooterMode {
|
||||
const configured = resolveChannelProgressDraftConfig(entry).status;
|
||||
return configured === "off" || configured === "minimal" || configured === "activity"
|
||||
|
||||
@@ -59,7 +59,7 @@ export type StatusFooterMode = "off" | "minimal" | "activity";
|
||||
export type ChannelStreamingProgressConfig = {
|
||||
/** Initial progress title. "auto" picks from labels; false hides the title. Default: "auto". */
|
||||
label?: string | false;
|
||||
/** Trailing status line: "activity" names the current work, "minimal" shows only elapsed time. Default: "activity". */
|
||||
/** Trailing status line: "activity" names the current work, "minimal" shows only elapsed time. Default: "off". */
|
||||
status?: StatusFooterMode;
|
||||
/** Candidate labels for label="auto". Defaults to OpenClaw's built-in progress labels. */
|
||||
labels?: string[];
|
||||
|
||||
Reference in New Issue
Block a user