docs: document agent test helpers

This commit is contained in:
Peter Steinberger
2026-06-04 06:44:16 -04:00
parent f5f046a736
commit f3a2488ab0
6 changed files with 41 additions and 4 deletions

View File

@@ -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 & {

View File

@@ -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<T>(fn: (home: string) => Promise<T>): Promise<T> {
// 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<T>(fn: (home: string) => Promise<T>): 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<T>(vars: string[], fn: () => Promise<T>): Promise<T> {
const previous: Record<string, string | undefined> = {};
for (const envVar of vars) {
@@ -74,12 +81,14 @@ export async function withTempEnv<T>(vars: string[], fn: () => Promise<T>): 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: {

View File

@@ -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<T>(
agentDir = resolveDefaultAgentDir({}),

View File

@@ -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,

View File

@@ -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<unknown>;
getRuntimeConfig: () => OpenClawConfig;

View File

@@ -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<SessionStore> {
try {
const raw = await fs.readFile(storePath, "utf8");
@@ -21,6 +27,7 @@ export async function readSubagentSessionStore(storePath: string): Promise<Sessi
return {};
}
/** Writes or updates one subagent session-store entry for persistence tests. */
export async function writeSubagentSessionEntry(params: {
stateDir: string;
sessionKey: string;
@@ -45,6 +52,7 @@ export async function writeSubagentSessionEntry(params: {
return storePath;
}
/** Removes one subagent session-store entry for persistence tests. */
export async function removeSubagentSessionEntry(params: {
stateDir: string;
sessionKey: string;
@@ -58,6 +66,7 @@ export async function removeSubagentSessionEntry(params: {
return storePath;
}
/** Builds default dependency mocks used by subagent registry persistence tests. */
export function createSubagentRegistryTestDeps(
extra: Record<string, unknown> = {},
): Record<string, unknown> {