mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-28 08:52:12 +00:00
fix(telegram): honor outbound media max bytes (#83478)
This commit is contained in:
@@ -372,6 +372,7 @@ export function createTelegramBotCore(
|
||||
groupAllowFrom,
|
||||
replyToMode,
|
||||
textLimit,
|
||||
mediaMaxBytes,
|
||||
useAccessGroups,
|
||||
nativeEnabled,
|
||||
nativeSkillsEnabled,
|
||||
|
||||
@@ -1790,6 +1790,7 @@ describe("dispatchTelegramMessage draft streaming", () => {
|
||||
|
||||
it("keeps streamed final text in place when late media arrives", async () => {
|
||||
const { answerDraftStream } = setupDraftStreams({ answerMessageId: 2001 });
|
||||
const mediaMaxBytes = 50 * 1024 * 1024;
|
||||
dispatchReplyWithBufferedBlockDispatcher.mockImplementation(
|
||||
async ({ dispatcherOptions, replyOptions }) => {
|
||||
await replyOptions?.onPartialReply?.({ text: "Photo" });
|
||||
@@ -1801,10 +1802,14 @@ describe("dispatchTelegramMessage draft streaming", () => {
|
||||
},
|
||||
);
|
||||
|
||||
await dispatchWithContext({ context: createContext() });
|
||||
await dispatchWithContext({
|
||||
context: createContext(),
|
||||
telegramCfg: { mediaMaxMb: 50 },
|
||||
});
|
||||
|
||||
expect(answerDraftStream.clear).not.toHaveBeenCalled();
|
||||
expect(answerDraftStream.update).toHaveBeenCalledWith("Photo");
|
||||
expectDeliverRepliesParams({ mediaMaxBytes });
|
||||
expectDeliveredReply(0, { text: undefined, mediaUrl: "https://example.com/a.png" });
|
||||
});
|
||||
|
||||
|
||||
@@ -228,7 +228,7 @@ type DispatchTelegramMessageParams = {
|
||||
textLimit: number;
|
||||
telegramCfg: TelegramAccountConfig;
|
||||
telegramDeps?: TelegramBotDeps;
|
||||
opts: Pick<TelegramBotOptions, "token">;
|
||||
opts: Pick<TelegramBotOptions, "token" | "mediaMaxMb">;
|
||||
};
|
||||
|
||||
type TelegramReasoningLevel = "off" | "on" | "stream";
|
||||
@@ -1001,6 +1001,7 @@ export const dispatchTelegramMessage = async ({
|
||||
runtime,
|
||||
bot,
|
||||
mediaLocalRoots,
|
||||
mediaMaxBytes: (opts.mediaMaxMb ?? telegramCfg.mediaMaxMb ?? 100) * 1024 * 1024,
|
||||
replyToMode,
|
||||
textLimit,
|
||||
thread: threadSpec,
|
||||
|
||||
@@ -59,8 +59,8 @@ function registerPlugCommand(params: PlugCommandHarnessParams = {}) {
|
||||
registerTelegramNativeCommands({
|
||||
...createNativeCommandTestParams(params.cfg ?? {}, {
|
||||
bot: botHarness.bot,
|
||||
...params.registerOverrides,
|
||||
}),
|
||||
...params.registerOverrides,
|
||||
});
|
||||
const handler = botHarness.commandHandlers.get("plug");
|
||||
if (!handler) {
|
||||
@@ -371,6 +371,7 @@ describe("registerTelegramNativeCommands", () => {
|
||||
});
|
||||
|
||||
it("passes agent-scoped media roots for plugin command replies with media", async () => {
|
||||
const mediaMaxBytes = 50 * 1024 * 1024;
|
||||
const cfg: OpenClawConfig = {
|
||||
agents: {
|
||||
list: [{ id: "main", default: true }, { id: "work" }],
|
||||
@@ -384,11 +385,15 @@ describe("registerTelegramNativeCommands", () => {
|
||||
text: "with media",
|
||||
mediaUrl: "/tmp/workspace-work/render.png",
|
||||
},
|
||||
registerOverrides: {
|
||||
mediaMaxBytes,
|
||||
} as Partial<Parameters<typeof registerTelegramNativeCommands>[0]>,
|
||||
});
|
||||
|
||||
await handler(createPrivateCommandContext());
|
||||
|
||||
const deliverParams = firstDeliverRepliesParams();
|
||||
expect(deliverParams.mediaMaxBytes).toBe(mediaMaxBytes);
|
||||
const mediaLocalRoots = deliverParams.mediaLocalRoots as Array<string> | undefined;
|
||||
expect(mediaLocalRoots?.some((root) => /[\\/]\.openclaw[\\/]workspace-work$/.test(root))).toBe(
|
||||
true,
|
||||
|
||||
@@ -467,6 +467,7 @@ export type RegisterTelegramNativeCommandsParams = {
|
||||
groupAllowFrom?: Array<string | number>;
|
||||
replyToMode: ReplyToMode;
|
||||
textLimit: number;
|
||||
mediaMaxBytes?: number;
|
||||
useAccessGroups: boolean;
|
||||
nativeEnabled: boolean;
|
||||
nativeSkillsEnabled: boolean;
|
||||
@@ -693,6 +694,7 @@ export const registerTelegramNativeCommands = ({
|
||||
groupAllowFrom,
|
||||
replyToMode,
|
||||
textLimit,
|
||||
mediaMaxBytes,
|
||||
useAccessGroups,
|
||||
nativeEnabled,
|
||||
nativeSkillsEnabled,
|
||||
@@ -933,6 +935,7 @@ export const registerTelegramNativeCommands = ({
|
||||
runtime,
|
||||
bot,
|
||||
mediaLocalRoots: params.mediaLocalRoots,
|
||||
mediaMaxBytes,
|
||||
replyToMode,
|
||||
textLimit,
|
||||
thread: params.threadSpec,
|
||||
|
||||
@@ -331,6 +331,7 @@ async function deliverMediaReply(params: {
|
||||
thread?: TelegramThreadSpec | null;
|
||||
tableMode?: MarkdownTableMode;
|
||||
mediaLocalRoots?: readonly string[];
|
||||
mediaMaxBytes?: number;
|
||||
chunkText: ChunkTextFn;
|
||||
mediaLoader: typeof loadWebMedia;
|
||||
onVoiceRecording?: () => Promise<void> | void;
|
||||
@@ -353,7 +354,10 @@ async function deliverMediaReply(params: {
|
||||
const isFirstMedia = first;
|
||||
const media = await params.mediaLoader(
|
||||
mediaUrl,
|
||||
buildOutboundMediaLoadOptions({ mediaLocalRoots: params.mediaLocalRoots }),
|
||||
buildOutboundMediaLoadOptions({
|
||||
mediaLocalRoots: params.mediaLocalRoots,
|
||||
maxBytes: params.mediaMaxBytes,
|
||||
}),
|
||||
);
|
||||
const kind = kindFromMime(media.contentType ?? undefined);
|
||||
const isGif = isGifMedia({
|
||||
@@ -693,6 +697,7 @@ export async function deliverReplies(params: {
|
||||
runtime: RuntimeEnv;
|
||||
bot: Bot;
|
||||
mediaLocalRoots?: readonly string[];
|
||||
mediaMaxBytes?: number;
|
||||
replyToMode: ReplyToMode;
|
||||
textLimit: number;
|
||||
thread?: TelegramThreadSpec | null;
|
||||
@@ -879,6 +884,7 @@ export async function deliverReplies(params: {
|
||||
thread: params.thread,
|
||||
tableMode: params.tableMode,
|
||||
mediaLocalRoots: params.mediaLocalRoots,
|
||||
mediaMaxBytes: params.mediaMaxBytes,
|
||||
chunkText,
|
||||
mediaLoader,
|
||||
onVoiceRecording: params.onVoiceRecording,
|
||||
|
||||
@@ -751,6 +751,33 @@ describe("deliverReplies", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("passes the configured media byte cap to media loading", async () => {
|
||||
const runtime = createRuntime();
|
||||
const sendPhoto = vi.fn().mockResolvedValue({
|
||||
message_id: 13,
|
||||
chat: { id: "123" },
|
||||
});
|
||||
const bot = createBot({ sendPhoto });
|
||||
const mediaMaxBytes = 50 * 1024 * 1024;
|
||||
|
||||
mockMediaLoad("photo.jpg", "image/jpeg", "image");
|
||||
|
||||
await deliverReplies({
|
||||
replies: [{ mediaUrl: "https://example.com/photo.jpg" }],
|
||||
chatId: "123",
|
||||
token: "tok",
|
||||
runtime,
|
||||
bot,
|
||||
replyToMode: "off",
|
||||
textLimit: 4000,
|
||||
mediaMaxBytes,
|
||||
});
|
||||
|
||||
expect(loadWebMedia).toHaveBeenCalledWith("https://example.com/photo.jpg", {
|
||||
maxBytes: mediaMaxBytes,
|
||||
});
|
||||
});
|
||||
|
||||
it("includes link_preview_options when linkPreview is false", async () => {
|
||||
const runtime = createRuntime();
|
||||
const sendMessage = vi.fn().mockResolvedValue({
|
||||
|
||||
Reference in New Issue
Block a user