From 56636dfe578f7bbef5eb2484414f3e4cf4b07436 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Thu, 7 May 2026 11:58:46 +0100 Subject: [PATCH] fix(ci): restore main validation --- .../server.roles-allowlist-update.test.ts | 35 +++++++++- .../codex-dynamic-tools.discord-group.json | 66 +++++++++++++++++++ .../codex-dynamic-tools.heartbeat-turn.json | 66 +++++++++++++++++++ .../codex-dynamic-tools.telegram-direct.json | 66 +++++++++++++++++++ .../discord-group-codex-message-tool.md | 14 ++-- .../telegram-direct-codex-message-tool.md | 14 ++-- .../telegram-heartbeat-codex-tool.md | 14 ++-- 7 files changed, 256 insertions(+), 19 deletions(-) diff --git a/src/gateway/server.roles-allowlist-update.test.ts b/src/gateway/server.roles-allowlist-update.test.ts index 72a70d62946..10706bc11d0 100644 --- a/src/gateway/server.roles-allowlist-update.test.ts +++ b/src/gateway/server.roles-allowlist-update.test.ts @@ -1,13 +1,14 @@ import fs from "node:fs/promises"; import os from "node:os"; import path from "node:path"; -import { describe, expect, test, vi } from "vitest"; +import { beforeEach, describe, expect, test, vi } from "vitest"; import { WebSocket } from "ws"; import type { DeviceIdentity } from "../infra/device-identity.js"; import { loadOrCreateDeviceIdentity } from "../infra/device-identity.js"; import { approveDevicePairing, listDevicePairing } from "../infra/device-pairing.js"; import { approveNodePairing, requestNodePairing } from "../infra/node-pairing.js"; import { resolveRestartSentinelPath } from "../infra/restart-sentinel.js"; +import { getActiveRuntimePluginRegistry } from "../plugins/active-runtime-registry.js"; import { GATEWAY_CLIENT_MODES, GATEWAY_CLIENT_NAMES } from "../utils/message-channel.js"; import type { GatewayClient } from "./client.js"; @@ -38,6 +39,38 @@ const FAST_WAIT_OPTS = { timeout: 1_000, interval: 2 } as const; let ws: WebSocket; let port: number; +function installCanvasNodePolicyForTest() { + const registry = getActiveRuntimePluginRegistry(); + if (!registry) { + throw new Error("active plugin registry is required for canvas node command tests"); + } + if ( + (registry.nodeInvokePolicies ?? []).some((entry) => + entry.policy.commands.includes("canvas.snapshot"), + ) + ) { + return; + } + registry.nodeInvokePolicies ??= []; + registry.nodeInvokePolicies.push({ + pluginId: "canvas", + pluginName: "Canvas", + source: "test", + rootDir: "extensions/canvas", + pluginConfig: {}, + policy: { + commands: ["canvas.snapshot"], + defaultPlatforms: ["ios", "android", "macos", "windows", "unknown"], + foregroundRestrictedOnIos: true, + handle: (ctx) => ctx.invokeNode(), + }, + }); +} + +beforeEach(() => { + installCanvasNodePolicyForTest(); +}); + installConnectedControlUiServerSuite((started) => { ws = started.ws; port = started.port; diff --git a/test/fixtures/agents/prompt-snapshots/codex-runtime-happy-path/codex-dynamic-tools.discord-group.json b/test/fixtures/agents/prompt-snapshots/codex-runtime-happy-path/codex-dynamic-tools.discord-group.json index 6db05c0e58c..fbf1026132a 100644 --- a/test/fixtures/agents/prompt-snapshots/codex-runtime-happy-path/codex-dynamic-tools.discord-group.json +++ b/test/fixtures/agents/prompt-snapshots/codex-runtime-happy-path/codex-dynamic-tools.discord-group.json @@ -1417,5 +1417,71 @@ "type": "object" }, "name": "web_fetch" + }, + { + "description": "Control node canvases (present/hide/navigate/eval/snapshot/A2UI). Use snapshot to capture the rendered UI.", + "inputSchema": { + "properties": { + "action": { + "enum": ["present", "hide", "navigate", "eval", "snapshot", "a2ui_push", "a2ui_reset"], + "type": "string" + }, + "delayMs": { + "type": "number" + }, + "gatewayToken": { + "type": "string" + }, + "gatewayUrl": { + "type": "string" + }, + "height": { + "type": "number" + }, + "javaScript": { + "type": "string" + }, + "jsonl": { + "type": "string" + }, + "jsonlPath": { + "type": "string" + }, + "maxWidth": { + "type": "number" + }, + "node": { + "type": "string" + }, + "outputFormat": { + "enum": ["png", "jpg", "jpeg"], + "type": "string" + }, + "quality": { + "type": "number" + }, + "target": { + "type": "string" + }, + "timeoutMs": { + "type": "number" + }, + "url": { + "type": "string" + }, + "width": { + "type": "number" + }, + "x": { + "type": "number" + }, + "y": { + "type": "number" + } + }, + "required": ["action"], + "type": "object" + }, + "name": "canvas" } ] diff --git a/test/fixtures/agents/prompt-snapshots/codex-runtime-happy-path/codex-dynamic-tools.heartbeat-turn.json b/test/fixtures/agents/prompt-snapshots/codex-runtime-happy-path/codex-dynamic-tools.heartbeat-turn.json index c6fcebb2611..44e730bdec9 100644 --- a/test/fixtures/agents/prompt-snapshots/codex-runtime-happy-path/codex-dynamic-tools.heartbeat-turn.json +++ b/test/fixtures/agents/prompt-snapshots/codex-runtime-happy-path/codex-dynamic-tools.heartbeat-turn.json @@ -1447,5 +1447,71 @@ "type": "object" }, "name": "web_fetch" + }, + { + "description": "Control node canvases (present/hide/navigate/eval/snapshot/A2UI). Use snapshot to capture the rendered UI.", + "inputSchema": { + "properties": { + "action": { + "enum": ["present", "hide", "navigate", "eval", "snapshot", "a2ui_push", "a2ui_reset"], + "type": "string" + }, + "delayMs": { + "type": "number" + }, + "gatewayToken": { + "type": "string" + }, + "gatewayUrl": { + "type": "string" + }, + "height": { + "type": "number" + }, + "javaScript": { + "type": "string" + }, + "jsonl": { + "type": "string" + }, + "jsonlPath": { + "type": "string" + }, + "maxWidth": { + "type": "number" + }, + "node": { + "type": "string" + }, + "outputFormat": { + "enum": ["png", "jpg", "jpeg"], + "type": "string" + }, + "quality": { + "type": "number" + }, + "target": { + "type": "string" + }, + "timeoutMs": { + "type": "number" + }, + "url": { + "type": "string" + }, + "width": { + "type": "number" + }, + "x": { + "type": "number" + }, + "y": { + "type": "number" + } + }, + "required": ["action"], + "type": "object" + }, + "name": "canvas" } ] diff --git a/test/fixtures/agents/prompt-snapshots/codex-runtime-happy-path/codex-dynamic-tools.telegram-direct.json b/test/fixtures/agents/prompt-snapshots/codex-runtime-happy-path/codex-dynamic-tools.telegram-direct.json index 019e513818e..559e9376693 100644 --- a/test/fixtures/agents/prompt-snapshots/codex-runtime-happy-path/codex-dynamic-tools.telegram-direct.json +++ b/test/fixtures/agents/prompt-snapshots/codex-runtime-happy-path/codex-dynamic-tools.telegram-direct.json @@ -1413,5 +1413,71 @@ "type": "object" }, "name": "web_fetch" + }, + { + "description": "Control node canvases (present/hide/navigate/eval/snapshot/A2UI). Use snapshot to capture the rendered UI.", + "inputSchema": { + "properties": { + "action": { + "enum": ["present", "hide", "navigate", "eval", "snapshot", "a2ui_push", "a2ui_reset"], + "type": "string" + }, + "delayMs": { + "type": "number" + }, + "gatewayToken": { + "type": "string" + }, + "gatewayUrl": { + "type": "string" + }, + "height": { + "type": "number" + }, + "javaScript": { + "type": "string" + }, + "jsonl": { + "type": "string" + }, + "jsonlPath": { + "type": "string" + }, + "maxWidth": { + "type": "number" + }, + "node": { + "type": "string" + }, + "outputFormat": { + "enum": ["png", "jpg", "jpeg"], + "type": "string" + }, + "quality": { + "type": "number" + }, + "target": { + "type": "string" + }, + "timeoutMs": { + "type": "number" + }, + "url": { + "type": "string" + }, + "width": { + "type": "number" + }, + "x": { + "type": "number" + }, + "y": { + "type": "number" + } + }, + "required": ["action"], + "type": "object" + }, + "name": "canvas" } ] diff --git a/test/fixtures/agents/prompt-snapshots/codex-runtime-happy-path/discord-group-codex-message-tool.md b/test/fixtures/agents/prompt-snapshots/codex-runtime-happy-path/discord-group-codex-message-tool.md index 8a8af8ab26f..502c0ac0073 100644 --- a/test/fixtures/agents/prompt-snapshots/codex-runtime-happy-path/discord-group-codex-message-tool.md +++ b/test/fixtures/agents/prompt-snapshots/codex-runtime-happy-path/discord-group-codex-message-tool.md @@ -95,7 +95,8 @@ "subagents", "session_status", "web_search", - "web_fetch" + "web_fetch", + "canvas" ], "experimentalRawEvents": true, "model": "gpt-5.5", @@ -213,8 +214,8 @@ This is the deterministic model-bound layer stack OpenClaw can snapshot for the "roughTokens": 158 }, "dynamicToolsJson": { - "chars": 49243, - "roughTokens": 12311 + "chars": 50870, + "roughTokens": 12718 }, "openClawDeveloperInstructions": { "chars": 6023, @@ -225,8 +226,8 @@ This is the deterministic model-bound layer stack OpenClaw can snapshot for the "roughTokens": 7294 }, "totalWithDynamicToolsJson": { - "chars": 78420, - "roughTokens": 19605 + "chars": 80047, + "roughTokens": 20012 }, "userInputText": { "chars": 870, @@ -588,7 +589,8 @@ Full JSON: `codex-dynamic-tools.discord-group.json` "subagents", "session_status", "web_search", - "web_fetch" + "web_fetch", + "canvas" ] ``` diff --git a/test/fixtures/agents/prompt-snapshots/codex-runtime-happy-path/telegram-direct-codex-message-tool.md b/test/fixtures/agents/prompt-snapshots/codex-runtime-happy-path/telegram-direct-codex-message-tool.md index fbd4cf2749f..c8c8aee8113 100644 --- a/test/fixtures/agents/prompt-snapshots/codex-runtime-happy-path/telegram-direct-codex-message-tool.md +++ b/test/fixtures/agents/prompt-snapshots/codex-runtime-happy-path/telegram-direct-codex-message-tool.md @@ -95,7 +95,8 @@ "subagents", "session_status", "web_search", - "web_fetch" + "web_fetch", + "canvas" ], "experimentalRawEvents": true, "model": "gpt-5.5", @@ -213,8 +214,8 @@ This is the deterministic model-bound layer stack OpenClaw can snapshot for the "roughTokens": 158 }, "dynamicToolsJson": { - "chars": 48934, - "roughTokens": 12234 + "chars": 50561, + "roughTokens": 12641 }, "openClawDeveloperInstructions": { "chars": 4999, @@ -225,8 +226,8 @@ This is the deterministic model-bound layer stack OpenClaw can snapshot for the "roughTokens": 6913 }, "totalWithDynamicToolsJson": { - "chars": 76587, - "roughTokens": 19147 + "chars": 78214, + "roughTokens": 19554 }, "userInputText": { "chars": 370, @@ -565,7 +566,8 @@ Full JSON: `codex-dynamic-tools.telegram-direct.json` "subagents", "session_status", "web_search", - "web_fetch" + "web_fetch", + "canvas" ] ``` diff --git a/test/fixtures/agents/prompt-snapshots/codex-runtime-happy-path/telegram-heartbeat-codex-tool.md b/test/fixtures/agents/prompt-snapshots/codex-runtime-happy-path/telegram-heartbeat-codex-tool.md index c49fccf69c9..75223e6785a 100644 --- a/test/fixtures/agents/prompt-snapshots/codex-runtime-happy-path/telegram-heartbeat-codex-tool.md +++ b/test/fixtures/agents/prompt-snapshots/codex-runtime-happy-path/telegram-heartbeat-codex-tool.md @@ -96,7 +96,8 @@ "subagents", "session_status", "web_search", - "web_fetch" + "web_fetch", + "canvas" ], "experimentalRawEvents": true, "model": "gpt-5.5", @@ -214,8 +215,8 @@ This is the deterministic model-bound layer stack OpenClaw can snapshot for the "roughTokens": 158 }, "dynamicToolsJson": { - "chars": 50057, - "roughTokens": 12515 + "chars": 51684, + "roughTokens": 12921 }, "openClawDeveloperInstructions": { "chars": 4999, @@ -226,8 +227,8 @@ This is the deterministic model-bound layer stack OpenClaw can snapshot for the "roughTokens": 7693 }, "totalWithDynamicToolsJson": { - "chars": 80828, - "roughTokens": 20207 + "chars": 82455, + "roughTokens": 20614 }, "userInputText": { "chars": 608, @@ -588,7 +589,8 @@ Full JSON: `codex-dynamic-tools.heartbeat-turn.json` "subagents", "session_status", "web_search", - "web_fetch" + "web_fetch", + "canvas" ] ```