From 2aa375149f4d9910b13b59b0cc1d0854efcd8e71 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sun, 26 Apr 2026 10:28:00 +0100 Subject: [PATCH] test: speed up agent hotspot tests --- src/agents/cli-runner.reliability.test.ts | 16 +++--- src/agents/cli-runner/prepare.test.ts | 50 +++++++++---------- .../attempt.spawn-workspace.test-support.ts | 11 ++++ .../pi-model-discovery.synthetic-auth.test.ts | 10 ++++ src/agents/runtime-plan/tools.test.ts | 32 +++++++++++- src/agents/sandbox/browser.create.test.ts | 26 ++++++++++ 6 files changed, 108 insertions(+), 37 deletions(-) diff --git a/src/agents/cli-runner.reliability.test.ts b/src/agents/cli-runner.reliability.test.ts index 9cc4d6e6375..8cb093c910d 100644 --- a/src/agents/cli-runner.reliability.test.ts +++ b/src/agents/cli-runner.reliability.test.ts @@ -24,15 +24,13 @@ import * as sessionHistoryModule from "./cli-runner/session-history.js"; import { MAX_CLI_SESSION_HISTORY_MESSAGES } from "./cli-runner/session-history.js"; import type { PreparedCliRunContext } from "./cli-runner/types.js"; -vi.mock("../plugins/hook-runner-global.js", async () => { - const actual = await vi.importActual( - "../plugins/hook-runner-global.js", - ); - return { - ...actual, - getGlobalHookRunner: vi.fn(() => null), - }; -}); +vi.mock("../plugins/hook-runner-global.js", () => ({ + getGlobalHookRunner: vi.fn(() => null), +})); + +vi.mock("../tts/tts.js", () => ({ + buildTtsSystemPromptHint: vi.fn(() => undefined), +})); const mockGetGlobalHookRunner = vi.mocked(getGlobalHookRunner); diff --git a/src/agents/cli-runner/prepare.test.ts b/src/agents/cli-runner/prepare.test.ts index e9685e63c42..23d4e81a780 100644 --- a/src/agents/cli-runner/prepare.test.ts +++ b/src/agents/cli-runner/prepare.test.ts @@ -15,35 +15,31 @@ import { shouldSkipLocalCliCredentialEpoch, } from "./prepare.js"; -vi.mock("../../plugins/hook-runner-global.js", async () => { - const actual = await vi.importActual( - "../../plugins/hook-runner-global.js", - ); - return { - ...actual, - getGlobalHookRunner: vi.fn(() => null), - }; -}); +vi.mock("../../plugins/hook-runner-global.js", () => ({ + getGlobalHookRunner: vi.fn(() => null), +})); -vi.mock("../video-generation-task-status.js", async () => { - const actual = await vi.importActual( - "../video-generation-task-status.js", - ); - return { - ...actual, - buildActiveVideoGenerationTaskPromptContextForSession: vi.fn(() => undefined), - }; -}); +vi.mock("../../tts/tts.js", () => ({ + buildTtsSystemPromptHint: vi.fn(() => undefined), +})); -vi.mock("../music-generation-task-status.js", async () => { - const actual = await vi.importActual( - "../music-generation-task-status.js", - ); - return { - ...actual, - buildActiveMusicGenerationTaskPromptContextForSession: vi.fn(() => undefined), - }; -}); +vi.mock("../video-generation-task-status.js", () => ({ + VIDEO_GENERATION_TASK_KIND: "video_generation", + buildActiveVideoGenerationTaskPromptContextForSession: vi.fn(() => undefined), + buildVideoGenerationTaskStatusDetails: vi.fn(() => ({})), + buildVideoGenerationTaskStatusText: vi.fn(() => ""), + findActiveVideoGenerationTaskForSession: vi.fn(() => undefined), + getVideoGenerationTaskProviderId: vi.fn(() => undefined), + isActiveVideoGenerationTask: vi.fn(() => false), +})); + +vi.mock("../music-generation-task-status.js", () => ({ + MUSIC_GENERATION_TASK_KIND: "music_generation", + buildActiveMusicGenerationTaskPromptContextForSession: vi.fn(() => undefined), + buildMusicGenerationTaskStatusDetails: vi.fn(() => ({})), + buildMusicGenerationTaskStatusText: vi.fn(() => ""), + findActiveMusicGenerationTaskForSession: vi.fn(() => undefined), +})); const mockGetGlobalHookRunner = vi.mocked(getGlobalHookRunner); const mockBuildActiveVideoGenerationTaskPromptContextForSession = vi.mocked( diff --git a/src/agents/pi-embedded-runner/run/attempt.spawn-workspace.test-support.ts b/src/agents/pi-embedded-runner/run/attempt.spawn-workspace.test-support.ts index 7a06cc4f8e1..31ac9a80104 100644 --- a/src/agents/pi-embedded-runner/run/attempt.spawn-workspace.test-support.ts +++ b/src/agents/pi-embedded-runner/run/attempt.spawn-workspace.test-support.ts @@ -234,6 +234,13 @@ vi.mock("../../../plugins/hook-runner-global.js", () => ({ initializeGlobalHookRunner: hoisted.initializeGlobalHookRunnerMock, })); +vi.mock("../../../plugins/provider-runtime.js", () => ({ + resolveProviderReasoningOutputModeWithPlugin: () => undefined, + resolveProviderSystemPromptContribution: () => undefined, + resolveProviderTextTransforms: () => undefined, + transformProviderSystemPrompt: ({ systemPrompt }: { systemPrompt: string }) => systemPrompt, +})); + vi.mock("../../../infra/machine-name.js", () => ({ getMachineDisplayName: async () => "test-host", })); @@ -246,6 +253,10 @@ vi.mock("../../../infra/net/undici-global-dispatcher.js", () => ({ hoisted.ensureGlobalUndiciStreamTimeoutsMock(...args), })); +vi.mock("../../../tts/tts.js", () => ({ + buildTtsSystemPromptHint: () => undefined, +})); + vi.mock("../../bootstrap-files.js", async () => { const actual = await vi.importActual( "../../bootstrap-files.js", diff --git a/src/agents/pi-model-discovery.synthetic-auth.test.ts b/src/agents/pi-model-discovery.synthetic-auth.test.ts index b5b987b9e87..fac72e895bc 100644 --- a/src/agents/pi-model-discovery.synthetic-auth.test.ts +++ b/src/agents/pi-model-discovery.synthetic-auth.test.ts @@ -29,6 +29,16 @@ vi.mock("../plugins/provider-runtime.js", () => ({ resolveExternalAuthProfilesWithPlugins: () => [], })); +vi.mock("./auth-profiles/store.js", () => ({ + ensureAuthProfileStore: () => ({ version: 1, profiles: {} }), + loadAuthProfileStoreForSecretsRuntime: () => ({ version: 1, profiles: {} }), +})); + +vi.mock("./pi-auth-discovery-core.js", () => ({ + addEnvBackedPiCredentials: (credentials: Record) => ({ ...credentials }), + scrubLegacyStaticAuthJsonEntriesForDiscovery: vi.fn(), +})); + let resolvePiCredentialsForDiscovery: typeof import("./pi-auth-discovery.js").resolvePiCredentialsForDiscovery; async function withAgentDir(run: (agentDir: string) => Promise): Promise { diff --git a/src/agents/runtime-plan/tools.test.ts b/src/agents/runtime-plan/tools.test.ts index 04e1a67f4ed..e98ea8d1cd0 100644 --- a/src/agents/runtime-plan/tools.test.ts +++ b/src/agents/runtime-plan/tools.test.ts @@ -1,5 +1,5 @@ import type { AgentTool } from "@mariozechner/pi-agent-core"; -import { describe, expect, it, vi } from "vitest"; +import { beforeEach, describe, expect, it, vi } from "vitest"; import { createNativeOpenAIResponsesModel, createParameterFreeTool, @@ -8,7 +8,22 @@ import { import { logAgentRuntimeToolDiagnostics, normalizeAgentRuntimeTools } from "./tools.js"; import type { AgentRuntimePlan } from "./types.js"; +const mocks = vi.hoisted(() => ({ + logProviderToolSchemaDiagnostics: vi.fn(), + normalizeProviderToolSchemas: vi.fn(), +})); + +vi.mock("../pi-embedded-runner/tool-schema-runtime.js", () => ({ + logProviderToolSchemaDiagnostics: mocks.logProviderToolSchemaDiagnostics, + normalizeProviderToolSchemas: mocks.normalizeProviderToolSchemas, +})); + describe("AgentRuntimePlan tool policy helpers", () => { + beforeEach(() => { + mocks.logProviderToolSchemaDiagnostics.mockReset(); + mocks.normalizeProviderToolSchemas.mockReset(); + }); + it("uses RuntimePlan-owned tool normalization when a plan is available", () => { const tools = [createParameterFreeTool()] as AgentTool[]; const normalized = [{ ...tools[0], name: "normalized" }] as AgentTool[]; @@ -65,6 +80,13 @@ describe("AgentRuntimePlan tool policy helpers", () => { }); it("falls back to legacy provider schema normalization when no plan is available", () => { + mocks.normalizeProviderToolSchemas.mockReturnValueOnce([ + { + ...createParameterFreeTool(), + parameters: normalizedParameterFreeSchema(), + }, + ]); + const normalized = normalizeAgentRuntimeTools({ tools: [createParameterFreeTool()] as AgentTool[], provider: "openai", @@ -75,6 +97,14 @@ describe("AgentRuntimePlan tool policy helpers", () => { }); expect(normalized[0]?.parameters).toEqual(normalizedParameterFreeSchema()); + expect(mocks.normalizeProviderToolSchemas).toHaveBeenCalledWith( + expect.objectContaining({ + provider: "openai", + modelId: "gpt-5.4", + modelApi: "openai-responses", + workspaceDir: "/tmp/openclaw-runtime-plan-tools", + }), + ); }); it("routes diagnostics through RuntimePlan when a plan is available", () => { diff --git a/src/agents/sandbox/browser.create.test.ts b/src/agents/sandbox/browser.create.test.ts index 4d0997a6731..ea7e515b037 100644 --- a/src/agents/sandbox/browser.create.test.ts +++ b/src/agents/sandbox/browser.create.test.ts @@ -51,6 +51,32 @@ vi.mock("../../plugin-sdk/browser-bridge.js", () => ({ stopBrowserBridgeServer: bridgeMocks.stopBrowserBridgeServer, })); +vi.mock("../../plugin-sdk/browser-profiles.js", () => ({ + DEFAULT_BROWSER_ACTION_TIMEOUT_MS: 60_000, + DEFAULT_BROWSER_EVALUATE_ENABLED: true, + DEFAULT_OPENCLAW_BROWSER_COLOR: "#FF4500", + DEFAULT_OPENCLAW_BROWSER_PROFILE_NAME: "openclaw", + resolveProfile: ( + resolved: { cdpHost: string; cdpIsLoopback: boolean; profiles?: Record }, + profileName: string, + ) => { + const profile = resolved.profiles?.[profileName] as { cdpPort?: number; color?: string }; + if (typeof profile?.cdpPort !== "number") { + return null; + } + return { + name: profileName, + cdpPort: profile.cdpPort, + cdpUrl: `http://${resolved.cdpHost}:${profile.cdpPort}`, + cdpHost: resolved.cdpHost, + cdpIsLoopback: resolved.cdpIsLoopback, + color: profile.color ?? "#FF4500", + driver: "openclaw", + attachOnly: true, + }; + }, +})); + async function loadFreshBrowserModulesForTest() { vi.resetModules(); ({ BROWSER_BRIDGES } = await import("./browser-bridges.js"));