mirror of
https://github.com/openclaw/openclaw.git
synced 2026-07-01 13:43:33 +00:00
[AI] fix(feishu): guard against missing inbound in channelRuntime fallback (#93466)
* [AI] fix(feishu): guard against missing inbound in channelRuntime fallback When channelRuntime from gateway context is truthy but lacks the inbound property, the ?? operator still selects it over getFeishuRuntime().channel, causing TypeError at core.channel.inbound.run(). The ChannelGatewayContext types channelRuntime as ChannelRuntimeSurface (only guarantees runtimeContexts), but channel.ts casts it to PluginRuntimeChannel via type assertion. If a partial runtime object without inbound is provided, the type lie becomes a runtime crash. Fix: check channelRuntime?.inbound before using it; fall back to getFeishuRuntime().channel when inbound is absent. Related to #93453 * [AI] test(feishu): add regression for partial channelRuntime lacking inbound When channelRuntime has runtimeContexts but no inbound, the guard in bot.ts should fall back to getFeishuRuntime().channel. Add a test that passes a partial channelRuntime and verifies dispatch does not crash. Refs #93453
This commit is contained in:
@@ -422,6 +422,7 @@ async function dispatchMessage(params: {
|
||||
cfg: ClawdbotConfig;
|
||||
currentCfg?: ClawdbotConfig;
|
||||
event: FeishuMessageEvent;
|
||||
channelRuntime?: PluginRuntime["channel"];
|
||||
}) {
|
||||
const runtime = createRuntimeEnv();
|
||||
const feishuConfig = params.cfg.channels?.feishu;
|
||||
@@ -443,6 +444,7 @@ async function dispatchMessage(params: {
|
||||
cfg,
|
||||
event: params.event,
|
||||
runtime,
|
||||
channelRuntime: params.channelRuntime,
|
||||
});
|
||||
return runtime;
|
||||
}
|
||||
@@ -960,6 +962,30 @@ describe("handleFeishuMessage ACP routing", () => {
|
||||
);
|
||||
expect(dispatcherOptions.allowReasoningPreview).toBe(true);
|
||||
});
|
||||
|
||||
it("falls back to full runtime channel when partial channelRuntime lacks inbound", async () => {
|
||||
const partialChannelRuntime = {
|
||||
runtimeContexts: {} as PluginRuntime["channel"]["runtimeContexts"],
|
||||
} as PluginRuntime["channel"];
|
||||
|
||||
await dispatchMessage({
|
||||
cfg: {
|
||||
session: { mainKey: "main", scope: "per-sender" },
|
||||
channels: { feishu: { enabled: true, allowFrom: ["ou_sender_1"], dmPolicy: "open" } },
|
||||
},
|
||||
event: {
|
||||
sender: { sender_id: { open_id: "ou_sender_1" } },
|
||||
message: {
|
||||
message_id: "msg-partial-runtime",
|
||||
chat_id: "oc_dm",
|
||||
chat_type: "p2p",
|
||||
message_type: "text",
|
||||
content: JSON.stringify({ text: "hello" }),
|
||||
},
|
||||
},
|
||||
channelRuntime: partialChannelRuntime,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("handleFeishuMessage command authorization", () => {
|
||||
|
||||
@@ -734,7 +734,7 @@ export async function handleFeishuMessage(params: {
|
||||
|
||||
try {
|
||||
const core = {
|
||||
channel: channelRuntime ?? getFeishuRuntime().channel,
|
||||
channel: channelRuntime?.inbound ? channelRuntime : getFeishuRuntime().channel,
|
||||
} as ReturnType<typeof getFeishuRuntime>;
|
||||
const pairing = createChannelPairingController({
|
||||
core,
|
||||
|
||||
Reference in New Issue
Block a user