Skip to content

Commit 3bf518e

Browse files
committed
fix(telegram): keep trajectory exports on turn lane
1 parent e3d802a commit 3bf518e

3 files changed

Lines changed: 21 additions & 4 deletions

File tree

extensions/telegram/src/sequential-key.test.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,14 @@ describe("getTelegramSequentialKey", () => {
146146
"telegram:123",
147147
],
148148
[{ message: mockMessage({ chat: mockChat({ id: 123 }), text: "/export" }) }, "telegram:123"],
149+
[
150+
{ message: mockMessage({ chat: mockChat({ id: 123 }), text: "/export-trajectory" }) },
151+
"telegram:123",
152+
],
153+
[
154+
{ message: mockMessage({ chat: mockChat({ id: 123 }), text: "/trajectory" }) },
155+
"telegram:123",
156+
],
149157
[
150158
{ message: mockMessage({ chat: mockChat({ id: 123 }), text: "/btw what is the time?" }) },
151159
"telegram:123:btw:1",

extensions/telegram/src/sequential-key.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import {
1111
} from "openclaw/plugin-sdk/command-primitives-runtime";
1212
import { resolveTelegramForumThreadId } from "./bot/helpers.js";
1313

14+
const TELEGRAM_NON_READ_ONLY_STATUS_COMMAND_KEYS = new Set(["export-session", "export-trajectory"]);
15+
1416
type TelegramSequentialKeyContext = {
1517
chat?: { id?: number };
1618
me?: UserFromGetMe;
@@ -32,9 +34,8 @@ export function isTelegramReadOnlyControlLaneText(params: {
3234
rawText?: string;
3335
botUsername?: string;
3436
}): boolean {
35-
// Only read-only status commands should bypass the per-topic lane. Commands
36-
// like /export-session stay on the normal lane because they materialize
37-
// session state to disk and should not interleave with an active turn.
37+
// Only read-only status commands should bypass the per-topic lane. Export
38+
// commands materialize mutable session state and should not interleave with an active turn.
3839
const normalizedBody = normalizeCommandBody(
3940
params.rawText?.trim() ?? "",
4041
params.botUsername ? { botUsername: params.botUsername } : undefined,
@@ -46,7 +47,9 @@ export function isTelegramReadOnlyControlLaneText(params: {
4647
const command = listChatCommands().find((entry) =>
4748
entry.textAliases.some((candidate) => candidate.trim().toLowerCase() === alias),
4849
);
49-
return command?.category === "status" && command.key !== "export-session";
50+
return (
51+
command?.category === "status" && !TELEGRAM_NON_READ_ONLY_STATUS_COMMAND_KEYS.has(command.key)
52+
);
5053
}
5154

5255
function isTelegramTargetedStopCommand(rawText?: string, botUsername?: string): boolean {

extensions/telegram/src/telegram-reply-fence.test.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,5 +36,11 @@ describe("shouldSupersedeTelegramReplyFence", () => {
3636
CommandAuthorized: false,
3737
}),
3838
).toBe(false);
39+
expect(
40+
shouldSupersedeTelegramReplyFence({
41+
CommandBody: "/export-trajectory bundle",
42+
CommandAuthorized: true,
43+
}),
44+
).toBe(true);
3945
});
4046
});

0 commit comments

Comments
 (0)