mirror of
https://github.com/moltbot/moltbot.git
synced 2026-04-21 05:32:53 +00:00
fix(gateway): pin startup channel registry
This commit is contained in:
@@ -51,6 +51,7 @@ Docs: https://docs.openclaw.ai
|
||||
- Voice-call/OpenAI: pass full plugin config into realtime transcription provider resolution so streaming calls can discover the bundled OpenAI realtime transcription provider again. Fixes #60936. Thanks @sliekens and @vincentkoc.
|
||||
- Plugins/OpenAI: enable `gpt-image-1` reference-image edits through `/images/edits` multipart uploads, and stop inferring unsupported resolution overrides when no explicit `size` or `resolution` is provided.
|
||||
- Gateway/startup: default `gateway.mode` to `local` when unset, detect PID recycling in gateway lock files on Windows and macOS, and show startup progress so healthy restarts stop getting blocked by stale locks. (#54801, #60085, #59843)
|
||||
- Gateway/channels: pin the initial startup channel registry before later plugin-registry churn so configured channels stay visible and `channels.status` stops falling back to empty `channelOrder` / `channels` payloads after runtime plugin loads.
|
||||
- Mobile pairing/Android: tighten secure endpoint handling so Tailscale and public remote setup reject cleartext endpoints, private LAN pairing still works, merged-role approvals mint both node and operator device tokens, and bootstrap tokens survive node auto-pair until operator approval finishes. (#60128, #60208, #60221)
|
||||
- Android/Talk Mode: restore spoken assistant replies on node-scoped sessions by keeping reply routing synced to the resolved node session key and pausing mic capture during reply playback. (#60306) Thanks @MKV21.
|
||||
- Telegram: fix current-model checks in the model picker, HTML-format non-default `/model` confirmations, explicit topic replies, persisted reaction ownership across restarts, caption-media placeholder and `file_id` preservation on download failure, and upgraded-install inbound image reads. (#60384, #60042, #59634, #59207, #59948, #59971)
|
||||
|
||||
@@ -91,7 +91,10 @@ export function prepareGatewayPluginLoad(params: GatewayPluginBootstrapParams) {
|
||||
export function loadGatewayStartupPlugins(
|
||||
params: Omit<GatewayPluginBootstrapParams, "beforePrimeRegistry">,
|
||||
) {
|
||||
return prepareGatewayPluginLoad(params);
|
||||
return prepareGatewayPluginLoad({
|
||||
...params,
|
||||
beforePrimeRegistry: pinActivePluginChannelRegistry,
|
||||
});
|
||||
}
|
||||
|
||||
export function reloadDeferredGatewayPlugins(
|
||||
|
||||
@@ -87,6 +87,7 @@ const createRegistry = (diagnostics: PluginDiagnostic[]): PluginRegistry => ({
|
||||
type ServerPluginsModule = typeof import("./server-plugins.js");
|
||||
type ServerPluginBootstrapModule = typeof import("./server-plugin-bootstrap.js");
|
||||
type PluginRuntimeModule = typeof import("../plugins/runtime/index.js");
|
||||
type PluginRuntimeRegistryModule = typeof import("../plugins/runtime.js");
|
||||
type GatewayRequestScopeModule = typeof import("../plugins/runtime/gateway-request-scope.js");
|
||||
type MethodScopesModule = typeof import("./method-scopes.js");
|
||||
type RuntimeStateModule = typeof import("../plugins/runtime-state.js");
|
||||
@@ -94,6 +95,7 @@ type RuntimeStateModule = typeof import("../plugins/runtime-state.js");
|
||||
let serverPluginsModule: ServerPluginsModule;
|
||||
let serverPluginBootstrapModule: ServerPluginBootstrapModule;
|
||||
let runtimeModule: PluginRuntimeModule;
|
||||
let runtimeRegistryModule: PluginRuntimeRegistryModule;
|
||||
let gatewayRequestScopeModule: GatewayRequestScopeModule;
|
||||
let methodScopesModule: MethodScopesModule;
|
||||
let getActivePluginRegistryWorkspaceDirFromState: typeof import("../plugins/runtime-state.js").getActivePluginRegistryWorkspaceDirFromState;
|
||||
@@ -131,6 +133,7 @@ async function loadTestModules() {
|
||||
serverPluginsModule = await import("./server-plugins.js");
|
||||
serverPluginBootstrapModule = await import("./server-plugin-bootstrap.js");
|
||||
runtimeModule = await import("../plugins/runtime/index.js");
|
||||
runtimeRegistryModule = await import("../plugins/runtime.js");
|
||||
gatewayRequestScopeModule = await import("../plugins/runtime/gateway-request-scope.js");
|
||||
methodScopesModule = await import("./method-scopes.js");
|
||||
const runtimeStateModule: RuntimeStateModule = await import("../plugins/runtime-state.js");
|
||||
@@ -230,6 +233,7 @@ beforeEach(() => {
|
||||
|
||||
afterEach(() => {
|
||||
runtimeModule.clearGatewaySubagentRuntime();
|
||||
runtimeRegistryModule.resetPluginRuntimeStateForTest();
|
||||
});
|
||||
|
||||
describe("loadGatewayPlugins", () => {
|
||||
@@ -287,6 +291,20 @@ describe("loadGatewayPlugins", () => {
|
||||
);
|
||||
});
|
||||
|
||||
test("pins the initial startup channel registry against later active-registry churn", async () => {
|
||||
const startupRegistry = createRegistry([]);
|
||||
loadOpenClawPlugins.mockReturnValue(startupRegistry);
|
||||
|
||||
loadGatewayStartupPluginsForTest({
|
||||
pluginIds: ["slack"],
|
||||
});
|
||||
|
||||
const replacementRegistry = createRegistry([]);
|
||||
runtimeRegistryModule.setActivePluginRegistry(replacementRegistry);
|
||||
|
||||
expect(runtimeRegistryModule.getActivePluginChannelRegistry()).toBe(startupRegistry);
|
||||
});
|
||||
|
||||
test("keeps the raw activation source when a precomputed startup scope is reused", async () => {
|
||||
const rawConfig = { channels: { slack: { botToken: "x" } } };
|
||||
const resolvedConfig = {
|
||||
|
||||
Reference in New Issue
Block a user