From f3a2488ab06d18c7dfd6d35c4e0368fcc508f497 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Thu, 4 Jun 2026 06:44:16 -0400 Subject: [PATCH] docs: document agent test helpers --- src/agents/embedded-agent-subscribe.handlers.tools.ts | 9 +++++++++ src/agents/models-config.e2e-harness.ts | 10 ++++++++++ src/agents/models-config.test-utils.ts | 5 ++++- src/agents/subagent-announce.registry.runtime.ts | 6 +++++- src/agents/subagent-announce.test-support.ts | 6 ++++-- .../subagent-registry.persistence.test-support.ts | 9 +++++++++ 6 files changed, 41 insertions(+), 4 deletions(-) diff --git a/src/agents/embedded-agent-subscribe.handlers.tools.ts b/src/agents/embedded-agent-subscribe.handlers.tools.ts index 5951117d036..9a1a2d25a4b 100644 --- a/src/agents/embedded-agent-subscribe.handlers.tools.ts +++ b/src/agents/embedded-agent-subscribe.handlers.tools.ts @@ -1,3 +1,8 @@ +/** + * Handles embedded-agent tool execution events and turns them into channel UI, + * replay state, hook calls, approval prompts, media queues, and agent-event + * telemetry. + */ import { asOptionalObjectRecord, asOptionalRecord as readRecordField, @@ -200,6 +205,7 @@ function buildToolStartKey(runId: string, toolCallId: string): string { return `${runId}:${toolCallId}`; } +/** Returns the number of active tool executions tracked for one embedded run. */ export function countActiveToolExecutions(runId: string): number { const prefix = `${runId}:`; let count = 0; @@ -846,6 +852,7 @@ async function emitToolResultOutput(params: { }); } +/** Handles a tool-execution start event and emits UI/telemetry start state. */ export function handleToolExecutionStart( ctx: ToolHandlerContext, evt: AgentEvent & { toolName: string; toolCallId: string; args: unknown }, @@ -1050,6 +1057,7 @@ export function handleToolExecutionStart( return continueAfterBlockReplyFlush(); } +/** Handles partial tool output and emits throttled live UI updates. */ export function handleToolExecutionUpdate( ctx: ToolHandlerContext, evt: AgentEvent & { @@ -1141,6 +1149,7 @@ export function handleToolExecutionUpdate( } } +/** Handles a tool-execution result and commits replay, media, hook, and error state. */ export async function handleToolExecutionEnd( ctx: ToolHandlerContext, evt: AgentEvent & { diff --git a/src/agents/models-config.e2e-harness.ts b/src/agents/models-config.e2e-harness.ts index 6b6d9c33cd8..5ec150ce370 100644 --- a/src/agents/models-config.e2e-harness.ts +++ b/src/agents/models-config.e2e-harness.ts @@ -1,3 +1,7 @@ +/** + * Models-config test harness utilities. The helpers isolate HOME, config + * caches, plugin loader state, fetch mocks, and ambient provider env vars. + */ import { afterEach, beforeEach } from "vitest"; import { clearConfigCache, clearRuntimeConfigSnapshot } from "../config/config.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; @@ -5,6 +9,7 @@ import { withTempHome as withTempHomeBase } from "../plugin-sdk/test-helpers/tem import { resetPluginLoaderTestStateForTest } from "../plugins/loader.test-fixtures.js"; import { resetModelsJsonReadyCacheForTest } from "./models-config-state.js"; +/** Runs a models-config test with an isolated temp HOME and no session cleanup. */ export function withModelsTempHome(fn: (home: string) => Promise): Promise { // Models-config tests do not exercise session persistence; skip draining // unrelated session lock state during temp-home teardown. @@ -14,6 +19,7 @@ export function withModelsTempHome(fn: (home: string) => Promise): Promise }); } +/** Installs before/after hooks that reset config, plugin, env, and fetch state. */ export function installModelsConfigTestHooks(opts?: { restoreFetch?: boolean; resetPluginLoaderState?: boolean; @@ -54,6 +60,7 @@ export function installModelsConfigTestHooks(opts?: { }); } +/** Temporarily clears or overrides a set of environment variables for one async test body. */ export async function withTempEnv(vars: string[], fn: () => Promise): Promise { const previous: Record = {}; for (const envVar of vars) { @@ -74,12 +81,14 @@ export async function withTempEnv(vars: string[], fn: () => Promise): Prom } } +/** Deletes environment variables used by models-config provider discovery. */ export function unsetEnv(vars: string[]) { for (const envVar of vars) { delete process.env[envVar]; } } +/** Ambient env vars cleared by implicit provider discovery tests. */ export const MODELS_CONFIG_IMPLICIT_ENV_VARS = [ "OPENCLAW_TEST_ONLY_PROVIDER_PLUGIN_IDS", "VITEST", @@ -138,6 +147,7 @@ export const MODELS_CONFIG_IMPLICIT_ENV_VARS = [ "AWS_SHARED_CREDENTIALS_FILE", ]; +/** Canonical custom proxy provider config used by models-config tests. */ export const CUSTOM_PROXY_MODELS_CONFIG: OpenClawConfig = { models: { providers: { diff --git a/src/agents/models-config.test-utils.ts b/src/agents/models-config.test-utils.ts index 8345e8884b6..aac3f0269ff 100644 --- a/src/agents/models-config.test-utils.ts +++ b/src/agents/models-config.test-utils.ts @@ -1,8 +1,11 @@ +/** + * Shared assertions helpers for models-config tests. These helpers read the + * generated agent-local model snapshot through the same path setup uses. + */ import fs from "node:fs/promises"; import path from "node:path"; import { resolveDefaultAgentDir } from "./agent-scope.js"; -// Test helper for reading the generated per-agent models snapshot. /** Read and parse the generated `models.json` file for assertions. */ export async function readGeneratedModelsJson( agentDir = resolveDefaultAgentDir({}), diff --git a/src/agents/subagent-announce.registry.runtime.ts b/src/agents/subagent-announce.registry.runtime.ts index b34f6641a71..54a535ee550 100644 --- a/src/agents/subagent-announce.registry.runtime.ts +++ b/src/agents/subagent-announce.registry.runtime.ts @@ -1,4 +1,8 @@ -// Runtime barrel for subagent announce registry helpers. +/** + * Runtime barrel for subagent announce registry helpers. Announce delivery + * imports this narrow surface so tests can replace registry behavior without + * loading the full persistence layer. + */ export { countActiveDescendantRuns, countPendingDescendantRuns, diff --git a/src/agents/subagent-announce.test-support.ts b/src/agents/subagent-announce.test-support.ts index 3863f362f57..f2d9f88ace3 100644 --- a/src/agents/subagent-announce.test-support.ts +++ b/src/agents/subagent-announce.test-support.ts @@ -1,11 +1,13 @@ +/** + * Test runtime factory for subagent announce delivery. It wires gateway, + * session-store, queue, and hook behavior to caller-provided mocks. + */ import type { OpenClawConfig } from "../config/types.openclaw.js"; import type { callGateway } from "../gateway/call.js"; import type { dispatchGatewayMethodInProcess } from "../gateway/server-plugins.js"; import type { EmbeddedAgentQueueMessageOptions } from "./embedded-agent-runner/run-state.js"; import type { EmbeddedAgentQueueMessageOutcome } from "./embedded-agent-runner/runs.js"; -// Test runtime for subagent announce delivery. It maps gateway calls, session -// store reads, and queue outcomes onto caller-provided mocks. type DeliveryRuntimeMockOptions = { callGateway: (request: unknown) => Promise; getRuntimeConfig: () => OpenClawConfig; diff --git a/src/agents/subagent-registry.persistence.test-support.ts b/src/agents/subagent-registry.persistence.test-support.ts index 19c3c613e48..31cccaf71b6 100644 --- a/src/agents/subagent-registry.persistence.test-support.ts +++ b/src/agents/subagent-registry.persistence.test-support.ts @@ -1,3 +1,8 @@ +/** + * Test helpers for subagent registry persistence scenarios. They create + * minimal session-store files and runtime dependency mocks without loading + * the production embedded-agent stack. + */ import fs from "node:fs/promises"; import path from "node:path"; import { vi } from "vitest"; @@ -8,6 +13,7 @@ function resolveSubagentSessionStorePath(stateDir: string, agentId: string): str return path.join(stateDir, "agents", agentId, "sessions", "sessions.json"); } +/** Reads a test session-store JSON file, returning an empty store on missing/invalid input. */ export async function readSubagentSessionStore(storePath: string): Promise { try { const raw = await fs.readFile(storePath, "utf8"); @@ -21,6 +27,7 @@ export async function readSubagentSessionStore(storePath: string): Promise = {}, ): Record {