diff --git a/CHANGELOG.md b/CHANGELOG.md index 740e0654008..3bcc0b955bb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,7 @@ Docs: https://docs.openclaw.ai - Agents/embedded replies: surface mid-turn 429 and overload failures when embedded runs end without a user-visible reply, while preserving successful media-only replies that still use legacy `mediaUrl`. (#50930) Thanks @infichen. - Agents/compaction: trigger timeout recovery compaction before retrying high-context LLM timeouts so embedded runs stop repeating oversized requests. (#46417) thanks @joeykrug. - Microsoft Teams/config: accept the existing `welcomeCard`, `groupWelcomeCard`, `promptStarters`, and feedback/reflection keys in strict config validation so already-supported Teams runtime settings stop failing schema checks. (#54679) Thanks @gumclaw. +- CLI/plugins: make routed commands use the same auto-enabled bundled-channel snapshot as gateway startup, so configured bundled channels like Slack load without requiring a prior config rewrite. (#54809) Thanks @neeravmakwana. - Agents/status: use provider-aware context window lookup for fresh Anthropic 4.6 model overrides so `/status` shows the correct 1.0m window instead of an underreported shared-cache minimum. (#54796) Thanks @neeravmakwana. - CLI/message send: write manual `openclaw message send` deliveries into the resolved agent session transcript again by always threading the default CLI agent through outbound mirroring. (#54187) Thanks @KevInTheCloud5617. - CLI/onboarding: show the Kimi Code API key option again in the Moonshot setup menu so the interactive picker includes all Kimi setup paths together. Fixes #54412 Thanks @sparkyrider diff --git a/src/cli/plugin-registry.test.ts b/src/cli/plugin-registry.test.ts index 30714b8a023..868a8f9c1df 100644 --- a/src/cli/plugin-registry.test.ts +++ b/src/cli/plugin-registry.test.ts @@ -1,6 +1,7 @@ import { beforeEach, describe, expect, it, vi } from "vitest"; const mocks = vi.hoisted(() => ({ + applyPluginAutoEnable: vi.fn(), resolveAgentWorkspaceDir: vi.fn(() => "/tmp/workspace"), resolveDefaultAgentId: vi.fn(() => "main"), loadConfig: vi.fn(), @@ -18,6 +19,10 @@ vi.mock("../config/config.js", () => ({ loadConfig: mocks.loadConfig, })); +vi.mock("../config/plugin-auto-enable.js", () => ({ + applyPluginAutoEnable: mocks.applyPluginAutoEnable, +})); + vi.mock("../plugins/loader.js", () => ({ loadOpenClawPlugins: mocks.loadOpenClawPlugins, })); @@ -34,17 +39,6 @@ describe("ensurePluginRegistryLoaded", () => { beforeEach(() => { vi.resetModules(); vi.clearAllMocks(); - mocks.loadConfig.mockReturnValue({ - plugins: { enabled: true }, - channels: { telegram: { enabled: false } }, - }); - mocks.loadPluginManifestRegistry.mockReturnValue({ - plugins: [ - { id: "telegram", channels: ["telegram"] }, - { id: "slack", channels: ["slack"] }, - { id: "openai", channels: [] }, - ], - }); mocks.getActivePluginRegistry.mockReturnValue({ plugins: [], channels: [], @@ -52,20 +46,75 @@ describe("ensurePluginRegistryLoaded", () => { }); }); - it("loads only configured channel plugins for configured-channels scope", async () => { + it("uses the auto-enabled config snapshot for configured channel scope", async () => { + const baseConfig = { + channels: { + slack: { + botToken: "xoxb-test", + appToken: "xapp-test", + }, + }, + }; + const autoEnabledConfig = { + ...baseConfig, + plugins: { + entries: { + slack: { + enabled: true, + }, + }, + }, + }; + + mocks.loadConfig.mockReturnValue(baseConfig); + mocks.applyPluginAutoEnable.mockReturnValue({ config: autoEnabledConfig, changes: [] }); + mocks.loadPluginManifestRegistry.mockReturnValue({ + plugins: [{ id: "slack", channels: ["slack"] }], + diagnostics: [], + }); + const { ensurePluginRegistryLoaded } = await import("./plugin-registry.js"); ensurePluginRegistryLoaded({ scope: "configured-channels" }); + expect(mocks.applyPluginAutoEnable).toHaveBeenCalledWith({ + config: baseConfig, + env: process.env, + }); + expect(mocks.resolveDefaultAgentId).toHaveBeenCalledWith(autoEnabledConfig); + expect(mocks.resolveAgentWorkspaceDir).toHaveBeenCalledWith(autoEnabledConfig, "main"); + expect(mocks.loadPluginManifestRegistry).toHaveBeenCalledWith( + expect.objectContaining({ + config: autoEnabledConfig, + workspaceDir: "/tmp/workspace", + }), + ); expect(mocks.loadOpenClawPlugins).toHaveBeenCalledWith( expect.objectContaining({ - onlyPluginIds: [], + config: autoEnabledConfig, + onlyPluginIds: ["slack"], throwOnLoadError: true, + workspaceDir: "/tmp/workspace", }), ); }); it("reloads when escalating from configured-channels to channels", async () => { + const config = { + plugins: { enabled: true }, + channels: { telegram: { enabled: false } }, + }; + + mocks.loadConfig.mockReturnValue(config); + mocks.applyPluginAutoEnable.mockReturnValue({ config, changes: [] }); + mocks.loadPluginManifestRegistry.mockReturnValue({ + plugins: [ + { id: "telegram", channels: ["telegram"] }, + { id: "slack", channels: ["slack"] }, + { id: "openai", channels: [] }, + ], + diagnostics: [], + }); mocks.getActivePluginRegistry .mockReturnValueOnce({ plugins: [], diff --git a/src/cli/plugin-registry.ts b/src/cli/plugin-registry.ts index 4656a1d3756..7b48a771427 100644 --- a/src/cli/plugin-registry.ts +++ b/src/cli/plugin-registry.ts @@ -1,5 +1,6 @@ import { resolveAgentWorkspaceDir, resolveDefaultAgentId } from "../agents/agent-scope.js"; import { loadConfig } from "../config/config.js"; +import { applyPluginAutoEnable } from "../config/plugin-auto-enable.js"; import { createSubsystemLogger } from "../logging.js"; import { resolveChannelPluginIds, @@ -44,7 +45,11 @@ export function ensurePluginRegistryLoaded(options?: { scope?: PluginRegistrySco return; } const config = loadConfig(); - const workspaceDir = resolveAgentWorkspaceDir(config, resolveDefaultAgentId(config)); + const resolvedConfig = applyPluginAutoEnable({ config, env: process.env }).config; + const workspaceDir = resolveAgentWorkspaceDir( + resolvedConfig, + resolveDefaultAgentId(resolvedConfig), + ); const logger: PluginLogger = { info: (msg) => log.info(msg), warn: (msg) => log.warn(msg), @@ -52,14 +57,14 @@ export function ensurePluginRegistryLoaded(options?: { scope?: PluginRegistrySco debug: (msg) => log.debug(msg), }; loadOpenClawPlugins({ - config, + config: resolvedConfig, workspaceDir, logger, throwOnLoadError: true, ...(scope === "configured-channels" ? { onlyPluginIds: resolveConfiguredChannelPluginIds({ - config, + config: resolvedConfig, workspaceDir, env: process.env, }), @@ -67,7 +72,7 @@ export function ensurePluginRegistryLoaded(options?: { scope?: PluginRegistrySco : scope === "channels" ? { onlyPluginIds: resolveChannelPluginIds({ - config, + config: resolvedConfig, workspaceDir, env: process.env, }),