From 8048ceca7141e5ee9dff07bc90e0636ae2ee152d Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Thu, 4 Jun 2026 15:10:14 -0400 Subject: [PATCH] docs: document agent identity tests --- src/agents/heartbeat-system-prompt.test.ts | 5 +++++ src/agents/hook-system-context-boundary.test.ts | 3 +++ src/agents/identity-avatar.test.ts | 8 +++++++- src/agents/identity.human-delay.test.ts | 3 +++ src/agents/identity.per-channel-prefix.test.ts | 5 +++++ src/agents/image-generation-task-status.test.ts | 8 ++++++++ src/agents/image-sanitization.test.ts | 1 + 7 files changed, 32 insertions(+), 1 deletion(-) diff --git a/src/agents/heartbeat-system-prompt.test.ts b/src/agents/heartbeat-system-prompt.test.ts index 7ff964c73bf..a82aca16aab 100644 --- a/src/agents/heartbeat-system-prompt.test.ts +++ b/src/agents/heartbeat-system-prompt.test.ts @@ -1,3 +1,4 @@ +// Verifies when heartbeat guidance is injected into the default agent prompt. import { describe, expect, it } from "vitest"; import { resolveHeartbeatPromptForSystemPrompt } from "./heartbeat-system-prompt.js"; @@ -65,6 +66,8 @@ describe("resolveHeartbeatPromptForSystemPrompt", () => { }); it("omits the heartbeat section when only a non-default agent has explicit heartbeat config", () => { + // The system prompt section is only for the default active agent; sibling + // agent heartbeat settings should not leak into the default prompt. expect( resolveHeartbeatPromptForSystemPrompt({ config: { @@ -87,6 +90,8 @@ describe("resolveHeartbeatPromptForSystemPrompt", () => { }); it("honors default-agent overrides for the prompt text", () => { + // Defaults establish cadence/shape, but the default agent can override the + // final visible prompt text. expect( resolveHeartbeatPromptForSystemPrompt({ config: { diff --git a/src/agents/hook-system-context-boundary.test.ts b/src/agents/hook-system-context-boundary.test.ts index 1832a75f19c..b888ebb7d62 100644 --- a/src/agents/hook-system-context-boundary.test.ts +++ b/src/agents/hook-system-context-boundary.test.ts @@ -1,7 +1,10 @@ +// Covers attribution boundaries around plugin-injected system context. import { describe, expect, it } from "vitest"; import { wrapPluginSystemContextSection } from "./hook-system-context-boundary.js"; function wrappedPluginSystemContext(text: string): string { + // The boundary text makes injected context explicit to the model so plugin + // instructions are not mistaken for workspace file content. return `---\n\nOpenClaw plugin-injected system context. This block is not workspace file content.\n\n${text}\n\n---`; } diff --git a/src/agents/identity-avatar.test.ts b/src/agents/identity-avatar.test.ts index aeb48184f66..9b345a6449f 100644 --- a/src/agents/identity-avatar.test.ts +++ b/src/agents/identity-avatar.test.ts @@ -1,3 +1,4 @@ +// Exercises agent avatar resolution, workspace containment, and public redaction. import fs from "node:fs/promises"; import os from "node:os"; import path from "node:path"; @@ -17,6 +18,8 @@ async function expectLocalAvatarPath( expectedRelativePath: string, opts?: Parameters[2], ) { + // Compare realpaths so symlinks or temp-dir normalization cannot hide an + // avatar escaping the configured workspace. const workspaceReal = await fs.realpath(workspace); const resolved = resolveAgentAvatar(cfg, "main", opts); expect(resolved.kind).toBe("local"); @@ -161,6 +164,8 @@ describe("resolveAgentAvatar", () => { expect(absolute.kind).toBe("none"); expect(resolvePublicAgentAvatarSource(absolute)).toBeUndefined(); + // Public status/UI surfaces may report remote/data origins, but local + // absolute paths and traversal attempts stay hidden. expect( resolvePublicAgentAvatarSource({ kind: "remote", @@ -247,7 +252,8 @@ describe("resolveAgentAvatar", () => { it("ui.assistant.avatar ignored without includeUiOverride (outbound callers)", async () => { const { cfg, workspace } = await setupUiAndConfigAvatarWorkspace(); - // Without the opt-in, outbound callers get the per-agent identity avatar, not the UI override. + // Without the opt-in, outbound callers get the per-agent identity avatar, + // not the UI override. await expectLocalAvatarPath(cfg, workspace, "cfg-avatar.png"); }); diff --git a/src/agents/identity.human-delay.test.ts b/src/agents/identity.human-delay.test.ts index c2fd298578a..b9e0b9f3381 100644 --- a/src/agents/identity.human-delay.test.ts +++ b/src/agents/identity.human-delay.test.ts @@ -1,3 +1,4 @@ +// Covers human-delay identity config inheritance. import { describe, expect, it } from "vitest"; import type { OpenClawConfig } from "../config/config.js"; import { resolveHumanDelayConfig } from "./identity.js"; @@ -9,6 +10,8 @@ describe("resolveHumanDelayConfig", () => { }); it("merges defaults with per-agent overrides", () => { + // Partial agent overrides should preserve unspecified timing bounds from + // defaults while replacing the fields the agent owns. const cfg: OpenClawConfig = { agents: { defaults: { diff --git a/src/agents/identity.per-channel-prefix.test.ts b/src/agents/identity.per-channel-prefix.test.ts index 4cd4f913d56..0e1d272f5d3 100644 --- a/src/agents/identity.per-channel-prefix.test.ts +++ b/src/agents/identity.per-channel-prefix.test.ts @@ -1,3 +1,4 @@ +// Documents response-prefix cascade across global, channel, and account scopes. import { describe, expect, it } from "vitest"; import type { OpenClawConfig } from "../config/config.js"; import { resolveResponsePrefix, resolveEffectiveMessagesConfig } from "./identity.js"; @@ -38,6 +39,7 @@ describe("resolveResponsePrefix with per-channel override", () => { describe("channel-level prefix", () => { it("returns channel prefix when set, ignoring global", () => { + // Channel scope is more specific than the global messages default. const cfg = makeConfig({ messages: { responsePrefix: "[Global] " }, channels: { @@ -58,6 +60,7 @@ describe("resolveResponsePrefix with per-channel override", () => { }); it("channel empty string stops cascade (no global prefix applied)", () => { + // Empty string is an explicit operator choice, not an unset value. const cfg = makeConfig({ messages: { responsePrefix: "[Global] " }, channels: { @@ -229,6 +232,8 @@ describe("resolveResponsePrefix with per-channel override", () => { // ─── Full cascade ───────────────────────────────────────────────── describe("full 4-level cascade", () => { + // Specificity order: account, channel, agent/global identity fallback, + // then global messages config. const fullCfg = makeConfig({ agents: { list: [{ id: "main", identity: { name: "TestBot" } }], diff --git a/src/agents/image-generation-task-status.test.ts b/src/agents/image-generation-task-status.test.ts index 050d374b724..ffdf5b9eaa6 100644 --- a/src/agents/image-generation-task-status.test.ts +++ b/src/agents/image-generation-task-status.test.ts @@ -1,3 +1,4 @@ +// Verifies image-generation task lookup, duplicate guards, and prompt status text. import { beforeEach, describe, expect, it, vi } from "vitest"; import { buildActiveImageGenerationTaskPromptContextForSession, @@ -32,6 +33,7 @@ vi.mock("../tasks/runtime-internal.js", () => taskRuntimeInternalMocks); function expectActiveImageGenerationTask( task: ReturnType, ): NonNullable> { + // Narrows optional lookups in tests that need provider/status helper calls. if (task == null) { throw new Error("Expected active image generation task"); } @@ -180,6 +182,8 @@ describe("image generation task status", () => { }); it("uses a matching recent-start request key as a succeeded duplicate guard", () => { + // The request key ties a tool call to its persisted completion so the + // model gets status guidance instead of starting the same image twice. const now = Date.now(); recordRecentMediaGenerationTaskStartForSession({ sessionKey: "agent:main", @@ -228,6 +232,8 @@ describe("image generation task status", () => { }); it("does not use a delivery-blocked image task as a succeeded duplicate guard", () => { + // If completion delivery failed, suppressing a retry would strand the + // requester without an image even though the provider task succeeded. const now = Date.now(); recordRecentMediaGenerationTaskStartForSession({ sessionKey: "agent:main", @@ -312,6 +318,8 @@ describe("image generation task status", () => { }); it("preserves earlier recent request keys when another image request starts", () => { + // Multiple image requests can be active/recent in the same session; a new + // request must not erase an older request key that can still match status. const now = Date.now(); recordRecentMediaGenerationTaskStartForSession({ sessionKey: "agent:main", diff --git a/src/agents/image-sanitization.test.ts b/src/agents/image-sanitization.test.ts index 23a06b75b28..1ce3fe46599 100644 --- a/src/agents/image-sanitization.test.ts +++ b/src/agents/image-sanitization.test.ts @@ -1,3 +1,4 @@ +// Covers agent image-sanitization limit config normalization. import { describe, expect, it } from "vitest"; import type { OpenClawConfig } from "../config/config.js"; import { resolveImageSanitizationLimits } from "./image-sanitization.js";