mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-07 18:42:25 +00:00
fix(telegram): migrate retired native draft config
This commit is contained in:
@@ -319,7 +319,7 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
- `streaming.preview.toolProgress` controls whether tool/progress updates reuse the same edited preview message (default: `true` when preview streaming is active)
|
||||
- `streaming.preview.commandText` controls command/exec detail inside those tool-progress lines: `raw` (default, preserves released behavior) or `status` (tool label only)
|
||||
- `streaming.progress.commentary` (default: `false`) opts into assistant commentary/preamble text in the temporary progress draft
|
||||
- legacy `channels.telegram.streamMode` and boolean `streaming` values are detected; run `openclaw doctor --fix` to migrate them to `channels.telegram.streaming.mode`
|
||||
- legacy `channels.telegram.streamMode`, boolean `streaming` values, and retired native draft preview keys are detected; run `openclaw doctor --fix` to migrate them to current streaming config
|
||||
|
||||
Tool-progress preview updates are the short status lines shown while tools run, for example command execution, file reads, planning updates, patch summaries, or Codex preamble/commentary text in Codex app-server mode. Telegram keeps these enabled by default to match released OpenClaw behavior from `v2026.4.22` and later.
|
||||
|
||||
|
||||
@@ -37,6 +37,23 @@ function hasRetiredTelegramAccountDmConfig(value: unknown): boolean {
|
||||
return Object.values(accounts).some((account) => hasRetiredTelegramDmConfig(account));
|
||||
}
|
||||
|
||||
function hasRetiredTelegramNativeDraftConfig(value: unknown): boolean {
|
||||
const entry = asObjectRecord(value);
|
||||
const streaming = asObjectRecord(entry?.streaming);
|
||||
const preview = asObjectRecord(streaming?.preview);
|
||||
return (
|
||||
preview?.nativeToolProgress !== undefined || preview?.nativeToolProgressAllowFrom !== undefined
|
||||
);
|
||||
}
|
||||
|
||||
function hasRetiredTelegramAccountNativeDraftConfig(value: unknown): boolean {
|
||||
const accounts = asObjectRecord(value);
|
||||
if (!accounts) {
|
||||
return false;
|
||||
}
|
||||
return Object.values(accounts).some((account) => hasRetiredTelegramNativeDraftConfig(account));
|
||||
}
|
||||
|
||||
function removeRetiredTelegramDmConfig(params: {
|
||||
entry: Record<string, unknown>;
|
||||
pathPrefix: string;
|
||||
@@ -82,6 +99,41 @@ function removeRetiredTelegramDmConfig(params: {
|
||||
return { entry: updated, changed };
|
||||
}
|
||||
|
||||
function removeRetiredTelegramNativeDraftConfig(params: {
|
||||
entry: Record<string, unknown>;
|
||||
pathPrefix: string;
|
||||
changes: string[];
|
||||
}): { entry: Record<string, unknown>; changed: boolean } {
|
||||
const streaming = asObjectRecord(params.entry.streaming);
|
||||
const preview = asObjectRecord(streaming?.preview);
|
||||
if (
|
||||
!streaming ||
|
||||
!preview ||
|
||||
(preview.nativeToolProgress === undefined && preview.nativeToolProgressAllowFrom === undefined)
|
||||
) {
|
||||
return { entry: params.entry, changed: false };
|
||||
}
|
||||
|
||||
const nextPreview = { ...preview };
|
||||
delete nextPreview.nativeToolProgress;
|
||||
delete nextPreview.nativeToolProgressAllowFrom;
|
||||
const nextStreaming = { ...streaming };
|
||||
if (Object.keys(nextPreview).length > 0) {
|
||||
nextStreaming.preview = nextPreview;
|
||||
} else {
|
||||
delete nextStreaming.preview;
|
||||
}
|
||||
|
||||
const updated =
|
||||
Object.keys(nextStreaming).length > 0
|
||||
? { ...params.entry, streaming: nextStreaming }
|
||||
: Object.fromEntries(Object.entries(params.entry).filter(([key]) => key !== "streaming"));
|
||||
params.changes.push(
|
||||
`Removed ${params.pathPrefix}.streaming.preview native draft keys; Telegram previews now use rich send/edit messages.`,
|
||||
);
|
||||
return { entry: updated, changed: true };
|
||||
}
|
||||
|
||||
function resolveCompatibleDefaultGroupEntry(section: Record<string, unknown>): {
|
||||
groups: Record<string, unknown>;
|
||||
entry: Record<string, unknown>;
|
||||
@@ -118,6 +170,18 @@ export const legacyConfigRules: ChannelDoctorLegacyConfigRule[] = [
|
||||
'channels.telegram.accounts.<id>.dm and direct.<chatId>.threadReplies were removed; DM topic sessions now follow Telegram getMe.has_topics_enabled, so topics-enabled bots may use thread-scoped DM sessions. Run "openclaw doctor --fix".',
|
||||
match: hasRetiredTelegramAccountDmConfig,
|
||||
},
|
||||
{
|
||||
path: ["channels", "telegram"],
|
||||
message:
|
||||
'channels.telegram.streaming.preview.nativeToolProgress and nativeToolProgressAllowFrom were removed; Telegram previews now use rich send/edit messages. Run "openclaw doctor --fix".',
|
||||
match: hasRetiredTelegramNativeDraftConfig,
|
||||
},
|
||||
{
|
||||
path: ["channels", "telegram", "accounts"],
|
||||
message:
|
||||
'channels.telegram.accounts.<id>.streaming.preview.nativeToolProgress and nativeToolProgressAllowFrom were removed; Telegram previews now use rich send/edit messages. Run "openclaw doctor --fix".',
|
||||
match: hasRetiredTelegramAccountNativeDraftConfig,
|
||||
},
|
||||
{
|
||||
path: ["channels", "telegram"],
|
||||
message:
|
||||
@@ -154,6 +218,14 @@ export function normalizeCompatibilityConfig({
|
||||
updated = removedThreadReplies.entry;
|
||||
changed = changed || removedThreadReplies.changed;
|
||||
|
||||
const removedNativeDraft = removeRetiredTelegramNativeDraftConfig({
|
||||
entry: updated,
|
||||
pathPrefix: "channels.telegram",
|
||||
changes,
|
||||
});
|
||||
updated = removedNativeDraft.entry;
|
||||
changed = changed || removedNativeDraft.changed;
|
||||
|
||||
if (updated.groupMentionsOnly !== undefined) {
|
||||
const defaultGroupEntry = resolveCompatibleDefaultGroupEntry(updated);
|
||||
if (!defaultGroupEntry) {
|
||||
@@ -210,6 +282,15 @@ export function normalizeCompatibilityConfig({
|
||||
nextAccounts[accountId] = accountRemovedThreadReplies.entry;
|
||||
accountsChanged = true;
|
||||
}
|
||||
const accountRemovedNativeDraft = removeRetiredTelegramNativeDraftConfig({
|
||||
entry: nextAccounts[accountId] as Record<string, unknown>,
|
||||
pathPrefix: `channels.telegram.accounts.${accountId}`,
|
||||
changes,
|
||||
});
|
||||
if (accountRemovedNativeDraft.changed) {
|
||||
nextAccounts[accountId] = accountRemovedNativeDraft.entry;
|
||||
accountsChanged = true;
|
||||
}
|
||||
}
|
||||
if (accountsChanged) {
|
||||
updated = { ...updated, accounts: nextAccounts };
|
||||
|
||||
@@ -229,6 +229,52 @@ describe("telegram doctor", () => {
|
||||
]);
|
||||
});
|
||||
|
||||
it("removes retired native draft preview keys", () => {
|
||||
const normalize = telegramDoctor.normalizeCompatibilityConfig;
|
||||
if (!normalize) {
|
||||
throw new Error("expected telegram compatibility normalizer");
|
||||
}
|
||||
|
||||
const result = normalize({
|
||||
cfg: {
|
||||
channels: {
|
||||
telegram: {
|
||||
streaming: {
|
||||
mode: "partial",
|
||||
preview: {
|
||||
toolProgress: true,
|
||||
nativeToolProgress: true,
|
||||
nativeToolProgressAllowFrom: ["123"],
|
||||
},
|
||||
},
|
||||
accounts: {
|
||||
work: {
|
||||
streaming: {
|
||||
preview: {
|
||||
nativeToolProgress: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
} as never,
|
||||
});
|
||||
|
||||
const telegram = result.config.channels?.telegram;
|
||||
expect(telegram?.streaming).toEqual({
|
||||
mode: "partial",
|
||||
preview: {
|
||||
toolProgress: true,
|
||||
},
|
||||
});
|
||||
expect(telegram?.accounts?.work?.streaming).toBeUndefined();
|
||||
expect(result.changes).toEqual([
|
||||
"Removed channels.telegram.streaming.preview native draft keys; Telegram previews now use rich send/edit messages.",
|
||||
"Removed channels.telegram.accounts.work.streaming.preview native draft keys; Telegram previews now use rich send/edit messages.",
|
||||
]);
|
||||
});
|
||||
|
||||
it("finds invalid allowFrom entries across scopes", () => {
|
||||
const hits = scanTelegramInvalidAllowFromEntries({
|
||||
channels: {
|
||||
|
||||
Reference in New Issue
Block a user