mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 14:30:45 +00:00
@@ -1106,4 +1106,40 @@ describe("registerTelegramNativeCommands — session metadata", () => {
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it("sends an empty-response fallback when a plugin command returns undefined", async () => {
|
||||
pluginRuntimeMocks.executePluginCommand.mockResolvedValue(undefined as never);
|
||||
|
||||
const { handler } = registerAndResolveCommandHandler({
|
||||
commandName: "codex",
|
||||
cfg: { commands: { allowFrom: { telegram: ["200"] } } } as OpenClawConfig,
|
||||
useAccessGroups: false,
|
||||
pluginCommandSpecs: [
|
||||
{
|
||||
name: "codex",
|
||||
description: "Codex",
|
||||
acceptsArgs: true,
|
||||
},
|
||||
] as TelegramPluginCommandSpecs,
|
||||
});
|
||||
pluginRuntimeMocks.matchPluginCommand.mockReturnValue({
|
||||
command: {
|
||||
name: "codex",
|
||||
description: "Codex",
|
||||
handler: vi.fn(),
|
||||
pluginId: "openclaw-codex-app-server",
|
||||
pluginName: "Codex",
|
||||
requireAuth: true,
|
||||
},
|
||||
args: "status",
|
||||
});
|
||||
|
||||
await handler(createTelegramPrivateCommandContext({ match: "status" }));
|
||||
|
||||
expect(deliveryMocks.deliverReplies).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
replies: [{ text: "No response generated. Please try again." }],
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -29,6 +29,7 @@ import type {
|
||||
TelegramTopicConfig,
|
||||
} from "openclaw/plugin-sdk/config-types";
|
||||
import { resolveMarkdownTableMode } from "openclaw/plugin-sdk/markdown-table-runtime";
|
||||
import { resolveSendableOutboundReplyParts } from "openclaw/plugin-sdk/reply-payload";
|
||||
import { resolveAgentRoute } from "openclaw/plugin-sdk/routing";
|
||||
import { getRuntimeConfigSnapshot } from "openclaw/plugin-sdk/runtime-config-snapshot";
|
||||
import { danger, logVerbose } from "openclaw/plugin-sdk/runtime-env";
|
||||
@@ -249,6 +250,16 @@ function resolveTelegramNativeReplyChannelData(
|
||||
return result.channelData?.telegram as TelegramNativeReplyChannelData | undefined;
|
||||
}
|
||||
|
||||
function normalizeTelegramNativeReplyPayload(
|
||||
result: TelegramNativeReplyPayload | null | undefined,
|
||||
): TelegramNativeReplyPayload {
|
||||
return result && typeof result === "object" ? result : {};
|
||||
}
|
||||
|
||||
function hasRenderableTelegramNativeReplyPayload(result: TelegramNativeReplyPayload): boolean {
|
||||
return resolveSendableOutboundReplyParts(result).hasContent;
|
||||
}
|
||||
|
||||
function isEditableTelegramProgressResult(result: TelegramNativeReplyPayload): boolean {
|
||||
const telegramData = resolveTelegramNativeReplyChannelData(result);
|
||||
return Boolean(
|
||||
@@ -1276,23 +1287,25 @@ export const registerTelegramNativeCommands = ({
|
||||
threadId: threadSpec.id,
|
||||
});
|
||||
|
||||
const result = await nativeCommandRuntime.executePluginCommand({
|
||||
command: match.command,
|
||||
args: match.args,
|
||||
senderId,
|
||||
channel: "telegram",
|
||||
isAuthorizedSender: commandAuthorized,
|
||||
senderIsOwner,
|
||||
sessionKey: route.sessionKey,
|
||||
sessionId: sessionFileContext.sessionId,
|
||||
sessionFile: sessionFileContext.sessionFile,
|
||||
commandBody,
|
||||
config: runtimeCfg,
|
||||
from,
|
||||
to,
|
||||
accountId,
|
||||
messageThreadId: threadSpec.id,
|
||||
});
|
||||
const result = normalizeTelegramNativeReplyPayload(
|
||||
await nativeCommandRuntime.executePluginCommand({
|
||||
command: match.command,
|
||||
args: match.args,
|
||||
senderId,
|
||||
channel: "telegram",
|
||||
isAuthorizedSender: commandAuthorized,
|
||||
senderIsOwner,
|
||||
sessionKey: route.sessionKey,
|
||||
sessionId: sessionFileContext.sessionId,
|
||||
sessionFile: sessionFileContext.sessionFile,
|
||||
commandBody,
|
||||
config: runtimeCfg,
|
||||
from,
|
||||
to,
|
||||
accountId,
|
||||
messageThreadId: threadSpec.id,
|
||||
}),
|
||||
);
|
||||
|
||||
if (
|
||||
shouldSuppressLocalTelegramExecApprovalPrompt({
|
||||
@@ -1310,14 +1323,19 @@ export const registerTelegramNativeCommands = ({
|
||||
return;
|
||||
}
|
||||
|
||||
const deliverableResult = hasRenderableTelegramNativeReplyPayload(result)
|
||||
? result
|
||||
: { text: EMPTY_RESPONSE_FALLBACK };
|
||||
const progressResultText =
|
||||
typeof result.text === "string" && result.text.trim().length > 0 ? result.text : null;
|
||||
const telegramResultData = resolveTelegramNativeReplyChannelData(result);
|
||||
typeof deliverableResult.text === "string" && deliverableResult.text.trim().length > 0
|
||||
? deliverableResult.text
|
||||
: null;
|
||||
const telegramResultData = resolveTelegramNativeReplyChannelData(deliverableResult);
|
||||
if (
|
||||
progressMessageId != null &&
|
||||
telegramDeps.editMessageTelegram &&
|
||||
progressResultText &&
|
||||
isEditableTelegramProgressResult(result)
|
||||
isEditableTelegramProgressResult(deliverableResult)
|
||||
) {
|
||||
try {
|
||||
await telegramDeps.editMessageTelegram(chatId, progressMessageId, progressResultText, {
|
||||
@@ -1350,9 +1368,10 @@ export const registerTelegramNativeCommands = ({
|
||||
runtime,
|
||||
});
|
||||
await deliverReplies({
|
||||
replies: [result],
|
||||
replies: [deliverableResult],
|
||||
...deliveryBaseOptions,
|
||||
silent: runtimeTelegramCfg.silentErrorReplies === true && result.isError === true,
|
||||
silent:
|
||||
runtimeTelegramCfg.silentErrorReplies === true && deliverableResult.isError === true,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user