From da9f24dd2e941e0c20bb1d50ca42e35a4427c11b Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Thu, 26 Feb 2026 22:12:26 +0100 Subject: [PATCH] fix: add nodes default-node regression test (#27444) (thanks @carbaj03) --- CHANGELOG.md | 1 + src/agents/tools/nodes-utils.test.ts | 32 ++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 src/agents/tools/nodes-utils.test.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 2202be77a..d735f89d1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ Docs: https://docs.openclaw.ai ### Fixes +- Agents/Canvas default node resolution: when multiple connected canvas-capable nodes exist and no single `mac-*` candidate is selected, default to the first connected candidate instead of failing with `node required` for implicit-node canvas tool calls. Landed from contributor PR #27444 by @carbaj03. Thanks @carbaj03. - TUI/stream assembly: preserve streamed text across real tool-boundary drops without keeping stale streamed text when non-text blocks appear only in the final payload. Landed from contributor PR #27711 by @scz2011. (#27674) - Hooks/Internal `message:sent`: forward `sessionKey` on outbound sends from agent delivery, cron isolated delivery, gateway receipt acks, heartbeat sends, session-maintenance warnings, and restart-sentinel recovery so internal `message:sent` hooks consistently dispatch with session context. Landed from contributor PR #27584 by @qualiobra. Thanks @qualiobra. - Models/MiniMax auth header defaults: set `authHeader: true` for both onboarding-generated MiniMax API providers and implicit built-in MiniMax (`minimax`, `minimax-portal`) provider templates so first requests no longer fail with MiniMax `401 authentication_error` due to missing `Authorization` header. Landed from contributor PRs #27622 by @riccoyuanft and #27631 by @kevinWangSheng. (#27600, #15303) diff --git a/src/agents/tools/nodes-utils.test.ts b/src/agents/tools/nodes-utils.test.ts new file mode 100644 index 000000000..3fef8619d --- /dev/null +++ b/src/agents/tools/nodes-utils.test.ts @@ -0,0 +1,32 @@ +import { describe, expect, it } from "vitest"; +import type { NodeListNode } from "./nodes-utils.js"; +import { resolveNodeIdFromList } from "./nodes-utils.js"; + +function node(overrides: Partial & { nodeId: string }): NodeListNode { + return { + nodeId: overrides.nodeId, + caps: ["canvas"], + connected: true, + ...overrides, + }; +} + +describe("resolveNodeIdFromList defaults", () => { + it("falls back to first connected canvas-capable node when multiple non-Mac candidates exist", () => { + const nodes: NodeListNode[] = [ + node({ nodeId: "ios-1", platform: "ios" }), + node({ nodeId: "android-1", platform: "android" }), + ]; + + expect(resolveNodeIdFromList(nodes, undefined, true)).toBe("ios-1"); + }); + + it("preserves local Mac preference when exactly one local Mac candidate exists", () => { + const nodes: NodeListNode[] = [ + node({ nodeId: "ios-1", platform: "ios" }), + node({ nodeId: "mac-1", platform: "macos" }), + ]; + + expect(resolveNodeIdFromList(nodes, undefined, true)).toBe("mac-1"); + }); +});