mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 09:20:43 +00:00
fix(cli): narrow message plugin registry loads
This commit is contained in:
@@ -16,6 +16,7 @@ Docs: https://docs.openclaw.ai
|
||||
### Fixes
|
||||
|
||||
- Channels/Telegram: skip the optional webhook-info API call during polling-mode status checks and startup bot-label probes so long-polling setups avoid an unnecessary Telegram round trip. Carries forward #72990. Thanks @danielgruneberg.
|
||||
- CLI/message: load only the selected channel plugin for targeted `openclaw message` actions, and fall back to configured channel plugins when the channel must be inferred, so scripted sends avoid full bundled plugin registry scans. Fixes #73006. Thanks @jasonftl.
|
||||
- CLI/models: keep route-first `models status --json` stdout reserved for the JSON payload by routing auth-profile and startup diagnostics to stderr. Fixes #72962. Thanks @vishutdhar.
|
||||
- Sessions: ignore future-dated session activity timestamps during reset freshness checks and cap future `updatedAt` values at the merge boundary so clock-skewed messages cannot keep stale sessions alive forever. Fixes #72989. Thanks @martingarramon.
|
||||
- Plugins/CLI: allow managed plugin installs when the active extensions root is a symlink to a real state directory, while keeping nested target symlinks blocked and suppressing misleading hook-pack fallback errors for install-boundary failures. Fixes #72946. Thanks @mayank6136.
|
||||
|
||||
@@ -22,6 +22,7 @@ Channel selection:
|
||||
- `--channel` required if more than one channel is configured.
|
||||
- If exactly one channel is configured, it becomes the default.
|
||||
- Values: `discord|googlechat|imessage|matrix|mattermost|msteams|signal|slack|telegram|whatsapp` (Mattermost requires plugin)
|
||||
- `openclaw message` loads only the selected channel plugin when `--channel` or a channel-prefixed target is present; otherwise it loads configured channel plugins for default-channel inference.
|
||||
|
||||
Target formats (`--target`):
|
||||
|
||||
|
||||
@@ -96,11 +96,46 @@ describe("runMessageAction", () => {
|
||||
it("calls exit(0) after successful message delivery", async () => {
|
||||
await runSendAction();
|
||||
|
||||
expect(ensurePluginRegistryLoaded).toHaveBeenCalledOnce();
|
||||
expect(ensurePluginRegistryLoaded).toHaveBeenCalledWith({
|
||||
scope: "configured-channels",
|
||||
onlyPluginIds: ["discord"],
|
||||
});
|
||||
expect(exitMock).toHaveBeenCalledOnce();
|
||||
expect(exitMock).toHaveBeenCalledWith(0);
|
||||
});
|
||||
|
||||
it("loads configured channel plugins when no target channel is known yet", async () => {
|
||||
await runSendAction({ channel: undefined });
|
||||
|
||||
expect(ensurePluginRegistryLoaded).toHaveBeenCalledWith({
|
||||
scope: "configured-channels",
|
||||
});
|
||||
});
|
||||
|
||||
it("narrows plugin loading from a channel-prefixed target", async () => {
|
||||
await runSendAction({ channel: undefined, target: "telegram:12345" });
|
||||
|
||||
expect(ensurePluginRegistryLoaded).toHaveBeenCalledWith({
|
||||
scope: "configured-channels",
|
||||
onlyPluginIds: ["telegram"],
|
||||
});
|
||||
});
|
||||
|
||||
it("loads configured channel plugins for mixed broadcast target prefixes", async () => {
|
||||
const runMessageAction = createRunMessageAction();
|
||||
|
||||
await expect(
|
||||
runMessageAction("broadcast", {
|
||||
targets: ["discord:channel:1", "telegram:123"],
|
||||
message: "hi",
|
||||
}),
|
||||
).rejects.toThrow("exit");
|
||||
|
||||
expect(ensurePluginRegistryLoaded).toHaveBeenCalledWith({
|
||||
scope: "configured-channels",
|
||||
});
|
||||
});
|
||||
|
||||
it("runs gateway_stop hooks before exit when registered", async () => {
|
||||
hasHooksMock.mockReturnValueOnce(true);
|
||||
await runSendAction();
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { Command } from "commander";
|
||||
import { resolveMessageSecretScope } from "../../../cli/message-secret-scope.js";
|
||||
import { messageCommand } from "../../../commands/message.js";
|
||||
import { danger, setVerbose } from "../../../globals.js";
|
||||
import { CHANNEL_TARGET_DESCRIPTION } from "../../../infra/outbound/channel-target.js";
|
||||
@@ -6,7 +7,7 @@ import { runGlobalGatewayStopSafely } from "../../../plugins/hook-runner-global.
|
||||
import { defaultRuntime } from "../../../runtime.js";
|
||||
import { runCommandWithRuntime } from "../../cli-utils.js";
|
||||
import { createDefaultDeps } from "../../deps.js";
|
||||
import { ensurePluginRegistryLoaded } from "../../plugin-registry.js";
|
||||
import { ensurePluginRegistryLoaded, type PluginRegistryScope } from "../../plugin-registry.js";
|
||||
|
||||
export type MessageCliHelpers = {
|
||||
withMessageBase: (command: Command) => Command;
|
||||
@@ -31,6 +32,20 @@ async function runPluginStopHooks(): Promise<void> {
|
||||
});
|
||||
}
|
||||
|
||||
function resolveMessagePluginLoadOptions(
|
||||
opts: Record<string, unknown>,
|
||||
): { scope: PluginRegistryScope; onlyPluginIds?: string[] } | undefined {
|
||||
const scopedChannel = resolveMessageSecretScope({
|
||||
channel: opts.channel,
|
||||
target: opts.target,
|
||||
targets: opts.targets,
|
||||
}).channel;
|
||||
if (scopedChannel) {
|
||||
return { scope: "configured-channels", onlyPluginIds: [scopedChannel] };
|
||||
}
|
||||
return { scope: "configured-channels" };
|
||||
}
|
||||
|
||||
export function createMessageCliHelpers(
|
||||
message: Command,
|
||||
messageChannelOptions: string,
|
||||
@@ -50,7 +65,7 @@ export function createMessageCliHelpers(
|
||||
|
||||
const runMessageAction = async (action: string, opts: Record<string, unknown>) => {
|
||||
setVerbose(Boolean(opts.verbose));
|
||||
ensurePluginRegistryLoaded();
|
||||
ensurePluginRegistryLoaded(resolveMessagePluginLoadOptions(opts));
|
||||
const deps = createDefaultDeps();
|
||||
let failed = false;
|
||||
await runCommandWithRuntime(
|
||||
|
||||
Reference in New Issue
Block a user