fix(cron): lazily load runtime plugins to fix external channel resolu… · openclaw/openclaw@5779d48
medns
·
2026-05-15
·
via Recent Commits to openclaw:main
| Original file line number | Diff line number | Diff line change |
|---|
|
| 1 | +export { ensureRuntimePluginsLoaded } from "../../agents/runtime-plugins.js"; |
| Original file line number | Diff line number | Diff line change |
|---|
|
| 1 | +import { describe, expect, it } from "vitest"; |
| 2 | +import { makeIsolatedAgentTurnParams, setupRunCronIsolatedAgentTurnSuite } from "./run.suite-helpers.js"; |
| 3 | +import { |
| 4 | +loadRunCronIsolatedAgentTurn, |
| 5 | +ensureRuntimePluginsLoadedMock, |
| 6 | +} from "./run.test-harness.js"; |
| 7 | + |
| 8 | +const runCronIsolatedAgentTurn = await loadRunCronIsolatedAgentTurn(); |
| 9 | + |
| 10 | +describe("runCronIsolatedAgentTurn runtime plugins loading", () => { |
| 11 | +setupRunCronIsolatedAgentTurnSuite(); |
| 12 | + |
| 13 | +it("loads runtime plugins eagerly using the lazily loaded module", async () => { |
| 14 | +const params = makeIsolatedAgentTurnParams(); |
| 15 | + |
| 16 | +const result = await runCronIsolatedAgentTurn(params); |
| 17 | + |
| 18 | +expect(result.status).toBe("ok"); |
| 19 | +expect(ensureRuntimePluginsLoadedMock).toHaveBeenCalledOnce(); |
| 20 | +expect(ensureRuntimePluginsLoadedMock).toHaveBeenCalledWith({ |
| 21 | +config: expect.objectContaining({ |
| 22 | +agents: expect.objectContaining({ |
| 23 | +defaults: expect.any(Object), |
| 24 | +}), |
| 25 | +}), |
| 26 | +workspaceDir: "/tmp/workspace", // matches resolveAgentWorkspaceDir mock |
| 27 | +}); |
| 28 | +}); |
| 29 | +}); |
| Original file line number | Diff line number | Diff line change |
|---|
@@ -71,6 +71,7 @@ export const resolveSessionAuthProfileOverrideMock = createMock();
|
71 | 71 | export const resolveFastModeStateMock = createMock(); |
72 | 72 | export const getChannelPluginMock = createMock(); |
73 | 73 | export const retireSessionMcpRuntimeMock = createMock(); |
| 74 | +export const ensureRuntimePluginsLoadedMock = createMock(); |
74 | 75 | |
75 | 76 | const resolveBootstrapWarningSignaturesSeenMock = createMock(); |
76 | 77 | const resolveCronStyleNowMock = createMock(); |
@@ -141,6 +142,10 @@ vi.mock("./run-model-catalog.runtime.js", () => ({
|
141 | 142 | loadModelCatalog: loadModelCatalogMock, |
142 | 143 | })); |
143 | 144 | |
| 145 | +vi.mock("./run-runtime-plugins.runtime.js", () => ({ |
| 146 | +ensureRuntimePluginsLoaded: ensureRuntimePluginsLoadedMock, |
| 147 | +})); |
| 148 | + |
144 | 149 | vi.mock("./skills-snapshot.runtime.js", () => ({ |
145 | 150 | buildWorkspaceSkillSnapshot: buildWorkspaceSkillSnapshotMock, |
146 | 151 | canExecRequestNode: vi.fn(() => false), |
@@ -509,6 +514,7 @@ export function resetRunCronIsolatedAgentTurnHarness(): void {
|
509 | 514 | resetRunSessionMocks(); |
510 | 515 | setSessionRuntimeModelMock.mockReturnValue(undefined); |
511 | 516 | logWarnMock.mockReset(); |
| 517 | +ensureRuntimePluginsLoadedMock.mockReset(); |
512 | 518 | } |
513 | 519 | |
514 | 520 | export function clearFastTestEnv(): string | undefined { |
|
| Original file line number | Diff line number | Diff line change |
|---|
@@ -91,6 +91,9 @@ const cronDeliveryRuntimeLoader = createLazyImportLoader(() => import("./run-del
|
91 | 91 | const cronModelPreflightRuntimeLoader = createLazyImportLoader( |
92 | 92 | () => import("./model-preflight.runtime.js"), |
93 | 93 | ); |
| 94 | +const runtimePluginsLoader = createLazyImportLoader( |
| 95 | +() => import("./run-runtime-plugins.runtime.js"), |
| 96 | +); |
94 | 97 | |
95 | 98 | async function loadSessionStoreRuntime() { |
96 | 99 | return await sessionStoreRuntimeLoader.load(); |
@@ -124,6 +127,10 @@ async function loadCronModelPreflightRuntime() {
|
124 | 127 | return await cronModelPreflightRuntimeLoader.load(); |
125 | 128 | } |
126 | 129 | |
| 130 | +async function loadRuntimePlugins() { |
| 131 | +return await runtimePluginsLoader.load(); |
| 132 | +} |
| 133 | + |
127 | 134 | function hasConfiguredAuthProfiles(cfg: OpenClawConfig): boolean { |
128 | 135 | return ( |
129 | 136 | Boolean(cfg.auth?.profiles && Object.keys(cfg.auth.profiles).length > 0) || |
@@ -539,6 +546,12 @@ async function prepareCronRunContext(params: {
|
539 | 546 | }); |
540 | 547 | const workspaceDir = workspace.dir; |
541 | 548 | |
| 549 | +// Ensure channel plugins and external model providers are loaded into the registry. |
| 550 | +// Must happen before resolving models and delivery context to avoid multi-channel ambiguity |
| 551 | +// and missing provider errors. |
| 552 | +const { ensureRuntimePluginsLoaded } = await loadRuntimePlugins(); |
| 553 | +ensureRuntimePluginsLoaded({ config: cfgWithAgentDefaults, workspaceDir }); |
| 554 | + |
542 | 555 | const isGmailHook = hookExternalContentSource === "gmail"; |
543 | 556 | const now = Date.now(); |
544 | 557 | const cronSession = resolveCronSession({ |
|
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。