From a4ff3e19ea04a44ccc0fb129fbb46953d718f910 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Fri, 29 May 2026 03:40:00 +0100 Subject: [PATCH] test: repair gateway client boundary snapshots --- src/tui/gateway-chat.test.ts | 60 ++++++++++++------- .../codex-dynamic-tools.discord-group.json | 32 ++++++---- .../codex-dynamic-tools.heartbeat-turn.json | 32 ++++++---- .../codex-dynamic-tools.telegram-direct.json | 32 ++++++---- .../discord-group-codex-message-tool.md | 8 +-- .../telegram-direct-codex-message-tool.md | 8 +-- .../telegram-heartbeat-codex-tool.md | 8 +-- 7 files changed, 116 insertions(+), 64 deletions(-) diff --git a/src/tui/gateway-chat.test.ts b/src/tui/gateway-chat.test.ts index f21cd739b5f..13885a50f5b 100644 --- a/src/tui/gateway-chat.test.ts +++ b/src/tui/gateway-chat.test.ts @@ -515,30 +515,46 @@ describe("GatewayChatClient", () => { vi.useRealTimers(); }); - it("identifies the TUI as a tui client and skips device identity on insecure local ui paths", () => { - const client = new GatewayChatClient({ - url: "ws://127.0.0.1:18789", - token: "test-token", - preauthHandshakeTimeoutMs: 30_000, - allowInsecureLocalOperatorUi: true, + it("identifies the TUI as a tui client and skips device identity on insecure local ui paths", async () => { + const constructedOptions: Array> = []; + + vi.resetModules(); + vi.doMock("../gateway/client.js", async (importOriginal) => { + const actual = await importOriginal(); + class CapturingGatewayClient { + constructor(opts: Record) { + constructedOptions.push(opts); + } + start() {} + stop() {} + request() { + throw new Error("unexpected request"); + } + } + return { ...actual, GatewayClient: CapturingGatewayClient }; }); - expect( - (client as unknown as { client: { opts: { clientName?: string; mode?: string } } }).client - .opts.clientName, - ).toBe("openclaw-tui"); - expect( - (client as unknown as { client: { opts: { clientName?: string; mode?: string } } }).client - .opts.mode, - ).toBe("ui"); - expect( - (client as unknown as { client: { opts: { deviceIdentity?: unknown } } }).client.opts - .deviceIdentity, - ).toBeUndefined(); - expect( - (client as unknown as { client: { opts: { preauthHandshakeTimeoutMs?: number } } }).client - .opts.preauthHandshakeTimeoutMs, - ).toBe(30_000); + try { + const { GatewayChatClient: CapturingGatewayChatClient } = await import("./gateway-chat.js"); + const client = new CapturingGatewayChatClient({ + url: "ws://127.0.0.1:18789", + token: "test-token", + preauthHandshakeTimeoutMs: 30_000, + allowInsecureLocalOperatorUi: true, + }); + + expect(client.connection.allowInsecureLocalOperatorUi).toBe(true); + expect(constructedOptions).toHaveLength(1); + expect(constructedOptions[0]).toMatchObject({ + clientName: "openclaw-tui", + mode: "ui", + preauthHandshakeTimeoutMs: 30_000, + deviceIdentity: null, + }); + } finally { + vi.doUnmock("../gateway/client.js"); + vi.resetModules(); + } }); it("surfaces loopback block-mode start failures through disconnect handler", async () => { 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 fe473b56a41..aa58bb214d8 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 @@ -262,7 +262,8 @@ }, "after": { "description": "Failures before alert", - "type": "number" + "minimum": 1, + "type": "integer" }, "channel": { "description": "Alert channel", @@ -270,7 +271,8 @@ }, "cooldownMs": { "description": "Alert cooldown ms", - "type": "number" + "minimum": 0, + "type": "integer" }, "includeSkipped": { "description": "Skipped runs count toward alert", @@ -329,6 +331,7 @@ "type": "string" }, "timeoutSeconds": { + "minimum": 0, "type": "number" }, "toolsAllow": { @@ -346,7 +349,8 @@ "properties": { "anchorMs": { "description": "Start anchor ms (kind=every)", - "type": "number" + "minimum": 0, + "type": "integer" }, "at": { "description": "ISO-8601 time (kind=at)", @@ -354,7 +358,8 @@ }, "everyMs": { "description": "Interval ms (kind=every)", - "type": "number" + "minimum": 1, + "type": "integer" }, "expr": { "description": "Cron expr in tz wall-clock time; do not convert to UTC. Omitted tz => Gateway host local timezone. Example 6pm Shanghai daily: expr \"0 18 * * *\", tz \"Asia/Shanghai\".", @@ -367,7 +372,8 @@ }, "staggerMs": { "description": "Jitter ms (kind=cron)", - "type": "number" + "minimum": 0, + "type": "integer" }, "tz": { "description": "IANA timezone for cron wall-clock fields, e.g. \"Asia/Shanghai\"; omitted => Gateway host local timezone.", @@ -480,7 +486,8 @@ }, "after": { "description": "Failures before alert", - "type": "number" + "minimum": 1, + "type": "integer" }, "channel": { "description": "Alert channel", @@ -488,7 +495,8 @@ }, "cooldownMs": { "description": "Alert cooldown ms", - "type": "number" + "minimum": 0, + "type": "integer" }, "includeSkipped": { "description": "Skipped runs count toward alert", @@ -547,6 +555,7 @@ "type": "string" }, "timeoutSeconds": { + "minimum": 0, "type": "number" }, "toolsAllow": { @@ -564,7 +573,8 @@ "properties": { "anchorMs": { "description": "Start anchor ms (kind=every)", - "type": "number" + "minimum": 0, + "type": "integer" }, "at": { "description": "ISO-8601 time (kind=at)", @@ -572,7 +582,8 @@ }, "everyMs": { "description": "Interval ms (kind=every)", - "type": "number" + "minimum": 1, + "type": "integer" }, "expr": { "description": "Cron expr in tz wall-clock time; do not convert to UTC. Omitted tz => Gateway host local timezone. Example 6pm Shanghai daily: expr \"0 18 * * *\", tz \"Asia/Shanghai\".", @@ -585,7 +596,8 @@ }, "staggerMs": { "description": "Jitter ms (kind=cron)", - "type": "number" + "minimum": 0, + "type": "integer" }, "tz": { "description": "IANA timezone for cron wall-clock fields, e.g. \"Asia/Shanghai\"; omitted => Gateway host local timezone.", 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 c18d5a2407d..e7d45490553 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 @@ -262,7 +262,8 @@ }, "after": { "description": "Failures before alert", - "type": "number" + "minimum": 1, + "type": "integer" }, "channel": { "description": "Alert channel", @@ -270,7 +271,8 @@ }, "cooldownMs": { "description": "Alert cooldown ms", - "type": "number" + "minimum": 0, + "type": "integer" }, "includeSkipped": { "description": "Skipped runs count toward alert", @@ -329,6 +331,7 @@ "type": "string" }, "timeoutSeconds": { + "minimum": 0, "type": "number" }, "toolsAllow": { @@ -346,7 +349,8 @@ "properties": { "anchorMs": { "description": "Start anchor ms (kind=every)", - "type": "number" + "minimum": 0, + "type": "integer" }, "at": { "description": "ISO-8601 time (kind=at)", @@ -354,7 +358,8 @@ }, "everyMs": { "description": "Interval ms (kind=every)", - "type": "number" + "minimum": 1, + "type": "integer" }, "expr": { "description": "Cron expr in tz wall-clock time; do not convert to UTC. Omitted tz => Gateway host local timezone. Example 6pm Shanghai daily: expr \"0 18 * * *\", tz \"Asia/Shanghai\".", @@ -367,7 +372,8 @@ }, "staggerMs": { "description": "Jitter ms (kind=cron)", - "type": "number" + "minimum": 0, + "type": "integer" }, "tz": { "description": "IANA timezone for cron wall-clock fields, e.g. \"Asia/Shanghai\"; omitted => Gateway host local timezone.", @@ -480,7 +486,8 @@ }, "after": { "description": "Failures before alert", - "type": "number" + "minimum": 1, + "type": "integer" }, "channel": { "description": "Alert channel", @@ -488,7 +495,8 @@ }, "cooldownMs": { "description": "Alert cooldown ms", - "type": "number" + "minimum": 0, + "type": "integer" }, "includeSkipped": { "description": "Skipped runs count toward alert", @@ -547,6 +555,7 @@ "type": "string" }, "timeoutSeconds": { + "minimum": 0, "type": "number" }, "toolsAllow": { @@ -564,7 +573,8 @@ "properties": { "anchorMs": { "description": "Start anchor ms (kind=every)", - "type": "number" + "minimum": 0, + "type": "integer" }, "at": { "description": "ISO-8601 time (kind=at)", @@ -572,7 +582,8 @@ }, "everyMs": { "description": "Interval ms (kind=every)", - "type": "number" + "minimum": 1, + "type": "integer" }, "expr": { "description": "Cron expr in tz wall-clock time; do not convert to UTC. Omitted tz => Gateway host local timezone. Example 6pm Shanghai daily: expr \"0 18 * * *\", tz \"Asia/Shanghai\".", @@ -585,7 +596,8 @@ }, "staggerMs": { "description": "Jitter ms (kind=cron)", - "type": "number" + "minimum": 0, + "type": "integer" }, "tz": { "description": "IANA timezone for cron wall-clock fields, e.g. \"Asia/Shanghai\"; omitted => Gateway host local timezone.", 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 31ad62ab3ab..9cdcfdfb6e5 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 @@ -262,7 +262,8 @@ }, "after": { "description": "Failures before alert", - "type": "number" + "minimum": 1, + "type": "integer" }, "channel": { "description": "Alert channel", @@ -270,7 +271,8 @@ }, "cooldownMs": { "description": "Alert cooldown ms", - "type": "number" + "minimum": 0, + "type": "integer" }, "includeSkipped": { "description": "Skipped runs count toward alert", @@ -329,6 +331,7 @@ "type": "string" }, "timeoutSeconds": { + "minimum": 0, "type": "number" }, "toolsAllow": { @@ -346,7 +349,8 @@ "properties": { "anchorMs": { "description": "Start anchor ms (kind=every)", - "type": "number" + "minimum": 0, + "type": "integer" }, "at": { "description": "ISO-8601 time (kind=at)", @@ -354,7 +358,8 @@ }, "everyMs": { "description": "Interval ms (kind=every)", - "type": "number" + "minimum": 1, + "type": "integer" }, "expr": { "description": "Cron expr in tz wall-clock time; do not convert to UTC. Omitted tz => Gateway host local timezone. Example 6pm Shanghai daily: expr \"0 18 * * *\", tz \"Asia/Shanghai\".", @@ -367,7 +372,8 @@ }, "staggerMs": { "description": "Jitter ms (kind=cron)", - "type": "number" + "minimum": 0, + "type": "integer" }, "tz": { "description": "IANA timezone for cron wall-clock fields, e.g. \"Asia/Shanghai\"; omitted => Gateway host local timezone.", @@ -480,7 +486,8 @@ }, "after": { "description": "Failures before alert", - "type": "number" + "minimum": 1, + "type": "integer" }, "channel": { "description": "Alert channel", @@ -488,7 +495,8 @@ }, "cooldownMs": { "description": "Alert cooldown ms", - "type": "number" + "minimum": 0, + "type": "integer" }, "includeSkipped": { "description": "Skipped runs count toward alert", @@ -547,6 +555,7 @@ "type": "string" }, "timeoutSeconds": { + "minimum": 0, "type": "number" }, "toolsAllow": { @@ -564,7 +573,8 @@ "properties": { "anchorMs": { "description": "Start anchor ms (kind=every)", - "type": "number" + "minimum": 0, + "type": "integer" }, "at": { "description": "ISO-8601 time (kind=at)", @@ -572,7 +582,8 @@ }, "everyMs": { "description": "Interval ms (kind=every)", - "type": "number" + "minimum": 1, + "type": "integer" }, "expr": { "description": "Cron expr in tz wall-clock time; do not convert to UTC. Omitted tz => Gateway host local timezone. Example 6pm Shanghai daily: expr \"0 18 * * *\", tz \"Asia/Shanghai\".", @@ -585,7 +596,8 @@ }, "staggerMs": { "description": "Jitter ms (kind=cron)", - "type": "number" + "minimum": 0, + "type": "integer" }, "tz": { "description": "IANA timezone for cron wall-clock fields, e.g. \"Asia/Shanghai\"; omitted => Gateway host local timezone.", 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 330e59b7e17..1795bffa4bc 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 @@ -221,8 +221,8 @@ This is the deterministic model-bound layer stack OpenClaw can snapshot for the "roughTokens": 0 }, "dynamicToolsJson": { - "chars": 40744, - "roughTokens": 10186 + "chars": 41138, + "roughTokens": 10285 }, "openClawDeveloperInstructions": { "chars": 2988, @@ -233,8 +233,8 @@ This is the deterministic model-bound layer stack OpenClaw can snapshot for the "roughTokens": 6925 }, "totalWithDynamicToolsJson": { - "chars": 68446, - "roughTokens": 17112 + "chars": 68840, + "roughTokens": 17210 }, "userInputText": { "chars": 1629, 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 3080af609ee..5e3abd9655b 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 @@ -221,8 +221,8 @@ This is the deterministic model-bound layer stack OpenClaw can snapshot for the "roughTokens": 0 }, "dynamicToolsJson": { - "chars": 40465, - "roughTokens": 10117 + "chars": 40859, + "roughTokens": 10215 }, "openClawDeveloperInstructions": { "chars": 1964, @@ -233,8 +233,8 @@ This is the deterministic model-bound layer stack OpenClaw can snapshot for the "roughTokens": 6544 }, "totalWithDynamicToolsJson": { - "chars": 66643, - "roughTokens": 16661 + "chars": 67037, + "roughTokens": 16760 }, "userInputText": { "chars": 1129, 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 1a30cbb351f..54e9fa6b35f 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 @@ -222,8 +222,8 @@ This is the deterministic model-bound layer stack OpenClaw can snapshot for the "roughTokens": 0 }, "dynamicToolsJson": { - "chars": 41560, - "roughTokens": 10390 + "chars": 41954, + "roughTokens": 10489 }, "openClawDeveloperInstructions": { "chars": 1983, @@ -234,8 +234,8 @@ This is the deterministic model-bound layer stack OpenClaw can snapshot for the "roughTokens": 6780 }, "totalWithDynamicToolsJson": { - "chars": 68681, - "roughTokens": 17171 + "chars": 69075, + "roughTokens": 17269 }, "userInputText": { "chars": 1367,