fix: filter gateway node list locally

This commit is contained in:
Peter Steinberger
2026-04-24 07:31:59 +01:00
parent cb4fc58547
commit f85806b6d7
2 changed files with 36 additions and 4 deletions

View File

@@ -526,6 +526,29 @@ describe("loadGatewayPlugins", () => {
expect(typeof subagent?.getSession).toBe("function");
});
test("filters connected plugin nodes locally without sending unsupported node.list params", async () => {
loadOpenClawPlugins.mockReturnValue(createRegistry([]));
loadGatewayStartupPluginsForTest();
serverPluginsModule.setFallbackGatewayContext(createTestContext("nodes-list-filter"));
handleGatewayRequest.mockImplementationOnce(async (opts: HandleGatewayRequestOptions) => {
expect(opts.req.method).toBe("node.list");
opts.respond(true, {
nodes: [
{ nodeId: "connected", connected: true },
{ nodeId: "offline", connected: false },
],
});
});
const runtime = runtimeModule.createPluginRuntime({
allowGatewaySubagentBinding: true,
});
const result = await runtime.nodes.list({ connected: true });
expect(getLastDispatchedParams()).toEqual({});
expect(result.nodes).toEqual([{ nodeId: "connected", connected: true }]);
});
test("forwards provider and model overrides when the request scope is authorized", async () => {
const serverPlugins = serverPluginsModule;
const runtime = await createSubagentRuntime(serverPlugins);

View File

@@ -388,11 +388,20 @@ export function createGatewaySubagentRuntime(): PluginRuntime["subagent"] {
export function createGatewayNodesRuntime(): PluginRuntime["nodes"] {
return {
async list(params) {
const payload = await dispatchGatewayMethod<{ nodes?: unknown[] }>("node.list", {
...(params?.connected === true && { connected: true }),
});
const payload = await dispatchGatewayMethod<{ nodes?: unknown[] }>("node.list", {});
const nodes = Array.isArray(payload?.nodes) ? payload.nodes : [];
return { nodes: nodes as Awaited<ReturnType<PluginRuntime["nodes"]["list"]>>["nodes"] };
const filteredNodes =
params?.connected === true
? nodes.filter(
(node) =>
node !== null &&
typeof node === "object" &&
(node as { connected?: unknown }).connected === true,
)
: nodes;
return {
nodes: filteredNodes as Awaited<ReturnType<PluginRuntime["nodes"]["list"]>>["nodes"],
};
},
async invoke(params) {
const payload = await dispatchGatewayMethod<unknown>("node.invoke", {