fix: unretire restored plugin registries

This commit is contained in:
Eva
2026-05-01 23:01:52 +07:00
committed by Josh Lehman
parent 2e2fd5fa14
commit 599beba44a
6 changed files with 68 additions and 10 deletions

View File

@@ -1940,11 +1940,27 @@ export function createMatrixRoomMessageHandler(params: MatrixMonitorHandlerParam
onIdle: typingCallbacks.onIdle,
});
const pinnedMainDmOwner = isDirectMessage
? resolvePinnedMainDmOwnerFromAllowlist({
dmScope: cfg.session?.dmScope,
allowFrom: effectiveAllowFrom,
normalizeEntry: normalizeMatrixUserId,
})
? await (async () => {
const livePinnedCfg = core.config.current() as CoreConfig;
const livePinnedAllowlists = resolveMatrixAccountAllowlistConfig({
cfg: livePinnedCfg,
accountId,
});
const livePinnedDmAllowFrom = await resolveCachedLiveAllowlist({
cfg: livePinnedCfg,
entries: livePinnedAllowlists.dmAllowFrom,
startupResolvedEntries: allowFromResolvedEntries,
cache: liveDmAllowlistCache,
updateCache: (next) => {
liveDmAllowlistCache = next;
},
});
return resolvePinnedMainDmOwnerFromAllowlist({
dmScope: cfg.session?.dmScope,
allowFrom: livePinnedDmAllowFrom,
normalizeEntry: normalizeMatrixUserId,
});
})()
: null;
const turnResult = await core.channel.turn.run({

View File

@@ -27,16 +27,16 @@ function createNonInteractiveMigrationPrompter(runtime: RuntimeEnv): WizardPromp
async note(message, title) {
runtime.log(title ? `${title}\n${message}` : message);
},
select(params) {
async select(params) {
return unavailable(params.message);
},
multiselect(params) {
async multiselect(params) {
return unavailable(params.message);
},
text(params) {
async text(params) {
return unavailable(params.message);
},
confirm(params) {
async confirm(params) {
return unavailable(params.message);
},
progress(label) {

View File

@@ -85,6 +85,39 @@ describe("plugin run context lifecycle", () => {
).toEqual({ live: true });
});
it("allows run-context mutations after a previous registry is restored active", () => {
const { config, registry } = createPluginRegistryFixture();
let capturedApi: OpenClawPluginApi | undefined;
registerTestPlugin({
registry,
config,
record: createPluginRecord({
id: "restored-run-context-plugin",
name: "Restored Run Context Plugin",
}),
register(api) {
capturedApi = api;
},
});
setActivePluginRegistry(registry.registry);
setActivePluginRegistry(createEmptyPluginRegistry());
setActivePluginRegistry(registry.registry);
expect(
capturedApi?.setRunContext({
runId: "restored-run",
namespace: "state",
value: { restored: true },
}),
).toBe(true);
expect(
getPluginRunContext({
pluginId: "restored-run-context-plugin",
get: { runId: "restored-run", namespace: "state" },
}),
).toEqual({ restored: true });
});
it("does not let delayed non-terminal subscriptions resurrect closed run context", async () => {
let releaseToolHandler: (() => void) | undefined;
let delayedToolHandlerSawContext: unknown;

View File

@@ -18,9 +18,11 @@ describe("plugin host cleanup config fallback", () => {
it("records session store config failures while continuing runtime cleanup", async () => {
const registry = createEmptyPluginRegistry();
const cleanup = vi.fn();
registry.runtimeLifecycles ??= [];
registry.runtimeLifecycles.push({
pluginId: "cleanup-plugin",
pluginName: "Cleanup Plugin",
source: "test",
lifecycle: {
id: "runtime-cleanup",
cleanup,

View File

@@ -8,6 +8,12 @@ export function markPluginRegistryRetired(registry: PluginRegistry | null | unde
}
}
export function markPluginRegistryActive(registry: PluginRegistry | null | undefined): void {
if (registry) {
retiredRegistries.delete(registry);
}
}
export function isPluginRegistryRetired(registry: PluginRegistry): boolean {
return retiredRegistries.has(registry);
}

View File

@@ -5,7 +5,7 @@ import {
dispatchPluginAgentEventSubscriptions,
} from "./host-hook-runtime.js";
import { createEmptyPluginRegistry } from "./registry-empty.js";
import { markPluginRegistryRetired } from "./registry-lifecycle.js";
import { markPluginRegistryActive, markPluginRegistryRetired } from "./registry-lifecycle.js";
import type { PluginRegistry } from "./registry-types.js";
import {
PLUGIN_REGISTRY_STATE,
@@ -133,6 +133,7 @@ export function setActivePluginRegistry(
if (previousRegistry && previousRegistry !== registry) {
markPluginRegistryRetired(previousRegistry);
}
markPluginRegistryActive(registry);
state.activeRegistry = registry;
state.activeVersion += 1;
syncTrackedSurface(state.httpRoute, registry, true);