refactor: reduce plugin SDK test import overhead (#109333)

* refactor(test): split plugin SDK test helpers

* fix(test): align plugin SDK test subpaths
This commit is contained in:
Peter Steinberger
2026-07-16 13:55:23 -07:00
committed by GitHub
parent cfaa30a08f
commit 0631252f4b
63 changed files with 261 additions and 164 deletions
+2 -1
View File
@@ -59,7 +59,8 @@ longer package exports: `agent-runtime-test-contracts`,
`plugin-state-test-runtime`, `plugin-test-api`, `plugin-test-contracts`,
`plugin-test-runtime`, `provider-http-test-mocks`, `provider-test-contracts`,
`reply-payload-testing`, `sqlite-runtime-testing`, `test-env`, `test-fixtures`,
`test-node-mocks`, and `testing`. The private bundled helper surfaces
`test-live`, `test-live-auth`, `test-media-generation`,
`test-media-understanding`, `test-node-mocks`, and `testing`. The private bundled helper surfaces
`ssrf-runtime-internal` and `codex-native-task-runtime` are also repo-local
only.
+6 -1
View File
@@ -38,6 +38,8 @@ import { registerSingleProviderPlugin } from "openclaw/plugin-sdk/plugin-test-ru
import { describeOpenAIProviderRuntimeContract } from "openclaw/plugin-sdk/provider-test-contracts";
import { getProviderHttpMocks } from "openclaw/plugin-sdk/provider-http-test-mocks";
import { withEnv, withFetchPreconnect, withServer } from "openclaw/plugin-sdk/test-env";
import { isLiveTestEnabled } from "openclaw/plugin-sdk/test-live";
import { createRequestCaptureJsonFetch } from "openclaw/plugin-sdk/test-media-understanding";
import {
bundledPluginRoot,
createCliRuntimeCapture,
@@ -102,7 +104,10 @@ imports of that alias.
| `createTestRegistry` | Build a channel plugin registry fixture. Import from `plugin-sdk/plugin-test-runtime` or `plugin-sdk/channel-test-helpers` |
| `createEmptyPluginRegistry` | Build an empty plugin registry fixture. Import from `plugin-sdk/plugin-test-runtime` or `plugin-sdk/channel-test-helpers` |
| `setActivePluginRegistry` | Install a registry fixture for plugin runtime tests. Import from `plugin-sdk/plugin-test-runtime` or `plugin-sdk/channel-test-helpers` |
| `createRequestCaptureJsonFetch` | Capture JSON fetch requests in media helper tests. Import from `plugin-sdk/test-env` |
| `createRequestCaptureJsonFetch` | Capture JSON fetch requests in media helper tests. Import from `plugin-sdk/test-media-understanding` |
| `isLiveTestEnabled` | Gate opt-in live provider tests. Import from `plugin-sdk/test-live` |
| `collectProviderApiKeys` | Discover credentials for live provider tests. Import from `plugin-sdk/test-live-auth` |
| `parseProviderModelMap` | Parse music/video live-test model overrides. Import from `plugin-sdk/test-media-generation` |
| `withServer` | Run tests against a disposable local HTTP server. Import from `plugin-sdk/test-env` |
| `createMockIncomingRequest` | Build a minimal incoming HTTP request object. Import from `plugin-sdk/test-env` |
| `withFetchPreconnect` | Run fetch tests with preconnect hooks installed. Import from `plugin-sdk/test-env` |
@@ -3,7 +3,7 @@ import {
registerProviderPlugin,
requireRegisteredProvider,
} from "openclaw/plugin-sdk/plugin-test-runtime";
import { isLiveTestEnabled } from "openclaw/plugin-sdk/test-env";
import { isLiveTestEnabled } from "openclaw/plugin-sdk/test-live";
import { describe, expect, it } from "vitest";
import plugin from "./index.js";
+1 -1
View File
@@ -1,5 +1,5 @@
// Azure Speech tests cover tts plugin behavior.
import { installPinnedHostnameTestHooks } from "openclaw/plugin-sdk/test-env";
import { installPinnedHostnameTestHooks } from "openclaw/plugin-sdk/test-media-understanding";
import { afterEach, describe, expect, it, vi } from "vitest";
import {
azureSpeechTTS,
+1 -1
View File
@@ -7,7 +7,7 @@ import {
} from "openclaw/plugin-sdk/llm";
import { registerSingleProviderPlugin } from "openclaw/plugin-sdk/plugin-test-runtime";
import type { ModelDefinitionConfig } from "openclaw/plugin-sdk/provider-model-shared";
import { isLiveTestEnabled } from "openclaw/plugin-sdk/test-env";
import { isLiveTestEnabled } from "openclaw/plugin-sdk/test-live";
import { Type } from "typebox";
import { describe, expect, it } from "vitest";
import { runSingleProviderCatalog } from "../test-support/provider-model-test-helpers.js";
+2 -1
View File
@@ -10,8 +10,9 @@ export {
expectGeneratedTokenPersistedToGatewayAuth,
type CliRuntimeCapture,
} from "openclaw/plugin-sdk/test-fixtures";
export { createTempHomeEnv, isLiveTestEnabled } from "openclaw/plugin-sdk/test-env";
export { createTempHomeEnv } from "openclaw/plugin-sdk/test-env";
export type { TempHomeEnv } from "openclaw/plugin-sdk/test-env";
export { isLiveTestEnabled } from "openclaw/plugin-sdk/test-live";
export type { OpenClawConfig } from "openclaw/plugin-sdk/config-contracts";
export function useAutoCleanupTempDirTracker(registerCleanup: (cleanup: () => void) => unknown) {
+1 -1
View File
@@ -4,7 +4,7 @@ import {
createSingleUserPromptMessage,
extractNonEmptyAssistantText,
isLiveTestEnabled,
} from "openclaw/plugin-sdk/test-env";
} from "openclaw/plugin-sdk/test-live";
import { describe, expect, it } from "vitest";
import { BYTEPLUS_CODING_BASE_URL } from "./models.js";
+1 -1
View File
@@ -3,7 +3,7 @@ import { resolveDefaultAgentDir } from "openclaw/plugin-sdk/agent-runtime";
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-contracts";
import { createTestPluginApi } from "openclaw/plugin-sdk/plugin-test-api";
import { getRuntimeConfig } from "openclaw/plugin-sdk/runtime-config-snapshot";
import { isLiveTestEnabled } from "openclaw/plugin-sdk/test-env";
import { isLiveTestEnabled } from "openclaw/plugin-sdk/test-live";
import { beforeAll, describe, expect, it } from "vitest";
import plugin from "./index.js";
import { getComfyConfigForTesting } from "./test-support.js";
+1 -1
View File
@@ -4,7 +4,7 @@ import { tmpdir } from "node:os";
import { join } from "node:path";
import { CopilotClient, approveAll } from "@github/copilot-sdk";
import type { AgentHarnessAttemptParams } from "openclaw/plugin-sdk/agent-harness-runtime";
import { isLiveTestEnabled } from "openclaw/plugin-sdk/test-env";
import { isLiveTestEnabled } from "openclaw/plugin-sdk/test-live";
import { describe, expect, it, vi } from "vitest";
import { createCopilotAgentHarness } from "../harness.js";
import type { CopilotClientPool } from "./runtime.js";
+1 -1
View File
@@ -3,7 +3,7 @@ import {
runRealtimeSttLiveTest,
synthesizeElevenLabsLiveSpeech,
} from "openclaw/plugin-sdk/provider-test-contracts";
import { isLiveTestEnabled } from "openclaw/plugin-sdk/test-env";
import { isLiveTestEnabled } from "openclaw/plugin-sdk/test-live";
import { describe, expect, it } from "vitest";
import { transcribeDeepgramAudio } from "./audio.js";
import { buildDeepgramRealtimeTranscriptionProvider } from "./realtime-transcription-provider.js";
+1 -1
View File
@@ -3,7 +3,7 @@ import {
createAuthCaptureJsonFetch,
createRequestCaptureJsonFetch,
installPinnedHostnameTestHooks,
} from "openclaw/plugin-sdk/test-env";
} from "openclaw/plugin-sdk/test-media-understanding";
import { describe, expect, it, vi } from "vitest";
import { transcribeDeepgramAudio } from "./audio.js";
+1 -1
View File
@@ -10,7 +10,7 @@ import {
createSingleUserPromptMessage,
extractNonEmptyAssistantText,
isLiveTestEnabled,
} from "openclaw/plugin-sdk/test-env";
} from "openclaw/plugin-sdk/test-live";
import { Type } from "typebox";
import { describe, expect, it } from "vitest";
import { buildDeepSeekProvider } from "./provider-catalog.js";
@@ -1,6 +1,6 @@
// Discord tests cover live smoke plugin behavior.
import { Routes } from "discord-api-types/v10";
import { isLiveTestEnabled } from "openclaw/plugin-sdk/test-env";
import { isLiveTestEnabled } from "openclaw/plugin-sdk/test-live";
import { describe, expect, it } from "vitest";
import { parseApplicationIdFromToken } from "../probe.js";
import { RequestClient } from "./rest.js";
@@ -8,7 +8,7 @@ import {
runRealtimeSttLiveTest,
synthesizeElevenLabsLiveSpeech,
} from "openclaw/plugin-sdk/provider-test-contracts";
import { isLiveTestEnabled } from "openclaw/plugin-sdk/test-env";
import { isLiveTestEnabled } from "openclaw/plugin-sdk/test-live";
import { describe, expect, it } from "vitest";
import plugin from "./index.js";
import { elevenLabsMediaUnderstandingProvider } from "./media-understanding-provider.js";
@@ -5,7 +5,7 @@ import {
type Model,
type Tool,
} from "openclaw/plugin-sdk/llm";
import { extractNonEmptyAssistantText, isLiveTestEnabled } from "openclaw/plugin-sdk/test-env";
import { extractNonEmptyAssistantText, isLiveTestEnabled } from "openclaw/plugin-sdk/test-live";
import { Type } from "typebox";
import { describe, expect, it } from "vitest";
import { FEATHERLESS_DEFAULT_MODEL_ID } from "./models.js";
@@ -1,5 +1,5 @@
// Google Meet tests cover google meet plugin behavior.
import { isLiveTestEnabled } from "openclaw/plugin-sdk/test-env";
import { isLiveTestEnabled } from "openclaw/plugin-sdk/test-live";
import { describe, expect, it } from "vitest";
import { buildGoogleMeetExportManifest, googleMeetExportFileNames } from "./src/cli.js";
import {
+1 -1
View File
@@ -5,7 +5,7 @@ import {
requireRegisteredProvider,
} from "openclaw/plugin-sdk/plugin-test-runtime";
import { normalizeTranscriptForMatch } from "openclaw/plugin-sdk/provider-test-contracts";
import { isLiveTestEnabled } from "openclaw/plugin-sdk/test-env";
import { isLiveTestEnabled } from "openclaw/plugin-sdk/test-live";
import { describe, expect, it } from "vitest";
import plugin from "./index.js";
import { createGeminiWebSearchProvider } from "./src/gemini-web-search-provider.js";
@@ -1,10 +1,10 @@
// Google tests cover media understanding provider.video plugin behavior.
import { createServer, type Server } from "node:http";
import { withFetchPreconnect } from "openclaw/plugin-sdk/test-env";
import {
createRequestCaptureJsonFetch,
installPinnedHostnameTestHooks,
withFetchPreconnect,
} from "openclaw/plugin-sdk/test-env";
} from "openclaw/plugin-sdk/test-media-understanding";
import { describe, expect, it } from "vitest";
import { describeGeminiVideo, transcribeGeminiAudio } from "./media-understanding-provider.js";
import { resolveGoogleGenerativeAiHttpRequestConfig } from "./runtime-api.js";
+1 -1
View File
@@ -6,7 +6,7 @@ import {
registerProviderPlugin,
requireRegisteredProvider,
} from "openclaw/plugin-sdk/plugin-test-runtime";
import { isLiveTestEnabled } from "openclaw/plugin-sdk/test-env";
import { isLiveTestEnabled } from "openclaw/plugin-sdk/test-live";
import { describe, expect, it } from "vitest";
import plugin from "./index.js";
+1 -1
View File
@@ -1,5 +1,5 @@
// Gradium tests cover speech provider plugin behavior.
import { installPinnedHostnameTestHooks } from "openclaw/plugin-sdk/test-env";
import { installPinnedHostnameTestHooks } from "openclaw/plugin-sdk/test-media-understanding";
import { afterEach, describe, expect, it, vi } from "vitest";
import { buildGradiumSpeechProvider } from "./speech-provider.js";
+1 -1
View File
@@ -1,5 +1,5 @@
// Gradium tests cover tts plugin behavior.
import { installPinnedHostnameTestHooks } from "openclaw/plugin-sdk/test-env";
import { installPinnedHostnameTestHooks } from "openclaw/plugin-sdk/test-media-understanding";
import { afterEach, describe, expect, it, vi } from "vitest";
import { gradiumTTS } from "./tts.js";
+1 -1
View File
@@ -3,7 +3,7 @@ import {
registerProviderPlugin,
requireRegisteredProvider,
} from "openclaw/plugin-sdk/plugin-test-runtime";
import { isLiveTestEnabled } from "openclaw/plugin-sdk/test-env";
import { isLiveTestEnabled } from "openclaw/plugin-sdk/test-live";
import { describe, expect, it } from "vitest";
import plugin from "./index.js";
+1 -1
View File
@@ -1,6 +1,6 @@
// Meta live tests prove muse-spark-1.1 auth and Responses API completion.
import { streamSimple, type Model } from "openclaw/plugin-sdk/llm";
import { extractNonEmptyAssistantText, isLiveTestEnabled } from "openclaw/plugin-sdk/test-env";
import { extractNonEmptyAssistantText, isLiveTestEnabled } from "openclaw/plugin-sdk/test-live";
import { describe, expect, it } from "vitest";
import { buildMetaProvider } from "./provider-catalog.js";
import { wrapMetaProviderStream } from "./stream.js";
+1 -1
View File
@@ -1,5 +1,5 @@
// Microsoft tests cover microsoft plugin behavior.
import { isLiveTestEnabled } from "openclaw/plugin-sdk/test-env";
import { isLiveTestEnabled } from "openclaw/plugin-sdk/test-live";
import { describe, expect, it } from "vitest";
import { buildMicrosoftSpeechProvider } from "./speech-provider.js";
@@ -1,7 +1,7 @@
// Minimax tests cover image generation provider plugin behavior.
import * as providerAuth from "openclaw/plugin-sdk/provider-auth-runtime";
import * as providerHttp from "openclaw/plugin-sdk/provider-http";
import { installPinnedHostnameTestHooks } from "openclaw/plugin-sdk/test-env";
import { installPinnedHostnameTestHooks } from "openclaw/plugin-sdk/test-media-understanding";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import {
buildMinimaxImageGenerationProvider,
+1 -1
View File
@@ -4,7 +4,7 @@ import {
registerProviderPlugin,
requireRegisteredProvider,
} from "openclaw/plugin-sdk/plugin-test-runtime";
import { isLiveTestEnabled } from "openclaw/plugin-sdk/test-env";
import { isLiveTestEnabled } from "openclaw/plugin-sdk/test-live";
import { describe, expect, it } from "vitest";
import plugin from "./index.js";
import { buildMinimaxSpeechProvider } from "./speech-provider.js";
@@ -2,7 +2,7 @@
import {
createRequestCaptureJsonFetch,
installPinnedHostnameTestHooks,
} from "openclaw/plugin-sdk/test-env";
} from "openclaw/plugin-sdk/test-media-understanding";
import { describe, expect, it } from "vitest";
import { mistralMediaUnderstandingProvider } from "./media-understanding-provider.js";
+1 -1
View File
@@ -4,7 +4,7 @@ import {
runRealtimeSttLiveTest,
synthesizeElevenLabsLiveSpeech,
} from "openclaw/plugin-sdk/provider-test-contracts";
import { isLiveTestEnabled } from "openclaw/plugin-sdk/test-env";
import { isLiveTestEnabled } from "openclaw/plugin-sdk/test-live";
import { describe, expect, it } from "vitest";
import { mistralMediaUnderstandingProvider } from "./media-understanding-provider.js";
import { buildMistralRealtimeTranscriptionProvider } from "./realtime-transcription-provider.js";
@@ -2,7 +2,7 @@
import {
createRequestCaptureJsonFetch,
installPinnedHostnameTestHooks,
} from "openclaw/plugin-sdk/test-env";
} from "openclaw/plugin-sdk/test-media-understanding";
import { describe, expect, it } from "vitest";
import { moonshotMediaUnderstandingProvider } from "./media-understanding-provider.js";
+1 -1
View File
@@ -7,7 +7,7 @@ import {
type Tool,
} from "openclaw/plugin-sdk/llm";
import { registerSingleProviderPlugin } from "openclaw/plugin-sdk/plugin-test-runtime";
import { isLiveTestEnabled } from "openclaw/plugin-sdk/test-env";
import { isLiveTestEnabled } from "openclaw/plugin-sdk/test-live";
import { Type } from "typebox";
import { describe, expect, it } from "vitest";
import plugin from "./index.js";
@@ -10,11 +10,6 @@ import {
} from "openclaw/plugin-sdk/plugin-test-runtime";
import { getRuntimeConfig } from "openclaw/plugin-sdk/runtime-config-snapshot";
import {
DEFAULT_LIVE_MUSIC_MODELS,
collectProviderApiKeys,
encodePngRgba,
fillPixel,
getShellEnvAppliedKeys,
isAuthErrorMessage,
isBillingErrorMessage,
isLiveProfileKeyModeEnabled,
@@ -24,12 +19,18 @@ import {
isServerErrorMessage,
isTimeoutErrorMessage,
isTruthyEnvValue,
} from "openclaw/plugin-sdk/test-live";
import { collectProviderApiKeys, getShellEnvAppliedKeys } from "openclaw/plugin-sdk/test-live-auth";
import {
DEFAULT_LIVE_MUSIC_MODELS,
encodePngRgba,
fillPixel,
parseCsvFilter,
parseProviderModelMap,
redactLiveApiKey,
resolveConfiguredLiveMusicModels,
resolveLiveMusicAuthStore,
} from "openclaw/plugin-sdk/test-env";
} from "openclaw/plugin-sdk/test-media-generation";
import { describe, expect, it } from "vitest";
import falPlugin from "./fal/index.js";
import googlePlugin from "./google/index.js";
@@ -3,7 +3,7 @@ import {
createAuthCaptureJsonFetch,
createRequestCaptureJsonFetch,
installPinnedHostnameTestHooks,
} from "openclaw/plugin-sdk/test-env";
} from "openclaw/plugin-sdk/test-media-understanding";
import { describe, expect, it } from "vitest";
import { openaiMediaUnderstandingProvider } from "./media-understanding-provider.js";
+1 -1
View File
@@ -1,5 +1,5 @@
// Openai tests cover openai tts plugin behavior.
import { isLiveTestEnabled } from "openclaw/plugin-sdk/test-env";
import { isLiveTestEnabled } from "openclaw/plugin-sdk/test-live";
import { describe, expect, it } from "vitest";
import { buildOpenAISpeechProvider } from "./speech-provider.js";
+1 -1
View File
@@ -17,7 +17,7 @@ import {
isOverloadedErrorMessage,
isServerErrorMessage,
isTimeoutErrorMessage,
} from "openclaw/plugin-sdk/test-env";
} from "openclaw/plugin-sdk/test-live";
import { describe, expect, it } from "vitest";
import plugin from "./index.js";
+1 -1
View File
@@ -5,7 +5,7 @@ import {
type Model,
type Tool,
} from "openclaw/plugin-sdk/llm";
import { extractNonEmptyAssistantText, isLiveTestEnabled } from "openclaw/plugin-sdk/test-env";
import { extractNonEmptyAssistantText, isLiveTestEnabled } from "openclaw/plugin-sdk/test-live";
import { Type } from "typebox";
import { describe, expect, it } from "vitest";
import { buildStaticOpencodeZenProviderConfig } from "./provider-catalog.js";
+1 -1
View File
@@ -1,4 +1,4 @@
import { isLiveTestEnabled } from "openclaw/plugin-sdk/test-env";
import { isLiveTestEnabled } from "openclaw/plugin-sdk/test-live";
import { describe, expect, it } from "vitest";
import { createParallelWebSearchProvider } from "./src/parallel-web-search-provider.js";
@@ -2,7 +2,7 @@
import {
createRequestCaptureJsonFetch,
installPinnedHostnameTestHooks,
} from "openclaw/plugin-sdk/test-env";
} from "openclaw/plugin-sdk/test-media-understanding";
import { describe, expect, it } from "vitest";
import { buildQwenMediaUnderstandingProvider } from "./media-understanding-provider.js";
@@ -8,7 +8,7 @@ import {
createAuthCaptureJsonFetch,
createRequestCaptureJsonFetch,
installPinnedHostnameTestHooks,
} from "openclaw/plugin-sdk/test-env";
} from "openclaw/plugin-sdk/test-media-understanding";
import { describe, expect, it } from "vitest";
import { senseaudioMediaUnderstandingProvider } from "./media-understanding-provider.js";
@@ -1,2 +1,2 @@
// Test Support helper module supports generation live test helpers behavior.
export { maybeLoadShellEnvForGenerationProviders } from "openclaw/plugin-sdk/test-env";
export { maybeLoadShellEnvForGenerationProviders } from "openclaw/plugin-sdk/test-live-auth";
@@ -53,6 +53,18 @@
"openclaw/plugin-sdk/test-fixtures": [
"../packages/plugin-sdk/dist/src/plugin-sdk/test-fixtures.d.ts"
],
"openclaw/plugin-sdk/test-live": [
"../packages/plugin-sdk/dist/src/plugin-sdk/test-live.d.ts"
],
"openclaw/plugin-sdk/test-live-auth": [
"../packages/plugin-sdk/dist/src/plugin-sdk/test-live-auth.d.ts"
],
"openclaw/plugin-sdk/test-media-generation": [
"../packages/plugin-sdk/dist/src/plugin-sdk/test-media-generation.d.ts"
],
"openclaw/plugin-sdk/test-media-understanding": [
"../packages/plugin-sdk/dist/src/plugin-sdk/test-media-understanding.d.ts"
],
"openclaw/plugin-sdk/test-node-mocks": [
"../packages/plugin-sdk/dist/src/plugin-sdk/test-node-mocks.d.ts"
],
@@ -10,13 +10,6 @@ import {
} from "openclaw/plugin-sdk/plugin-test-runtime";
import { getRuntimeConfig } from "openclaw/plugin-sdk/runtime-config-snapshot";
import {
DEFAULT_LIVE_VIDEO_MODELS,
canRunBufferBackedImageToVideoLiveLane,
canRunBufferBackedVideoToVideoLiveLane,
collectProviderApiKeys,
encodePngRgba,
fillPixel,
getShellEnvAppliedKeys,
isAuthErrorMessage,
isBillingErrorMessage,
isLiveProfileKeyModeEnabled,
@@ -26,6 +19,14 @@ import {
isServerErrorMessage,
isTimeoutErrorMessage,
isTruthyEnvValue,
} from "openclaw/plugin-sdk/test-live";
import { collectProviderApiKeys, getShellEnvAppliedKeys } from "openclaw/plugin-sdk/test-live-auth";
import {
DEFAULT_LIVE_VIDEO_MODELS,
canRunBufferBackedImageToVideoLiveLane,
canRunBufferBackedVideoToVideoLiveLane,
encodePngRgba,
fillPixel,
normalizeVideoGenerationDuration,
parseCsvFilter,
parseProviderModelMap,
@@ -34,14 +35,14 @@ import {
resolveConfiguredLiveVideoModels,
resolveLiveVideoAuthStore,
resolveLiveVideoResolution,
} from "openclaw/plugin-sdk/test-env";
} from "openclaw/plugin-sdk/test-media-generation";
import type {
GeneratedVideoAsset,
VideoGenerationMode,
VideoGenerationModeCapabilities,
VideoGenerationProvider,
VideoGenerationRequest,
} from "openclaw/plugin-sdk/test-env";
} from "openclaw/plugin-sdk/test-media-generation";
import { describe, expect, it } from "vitest";
import alibabaPlugin from "./alibaba/index.js";
import byteplusPlugin from "./byteplus/index.js";
@@ -1,5 +1,5 @@
// Vydra tests cover image generation provider plugin behavior.
import { installPinnedHostnameTestHooks } from "openclaw/plugin-sdk/test-env";
import { installPinnedHostnameTestHooks } from "openclaw/plugin-sdk/test-media-understanding";
import { afterEach, describe, expect, it, vi } from "vitest";
import { buildVydraImageGenerationProvider } from "./image-generation-provider.js";
import {
+1 -1
View File
@@ -1,5 +1,5 @@
// Vydra tests cover speech provider plugin behavior.
import { installPinnedHostnameTestHooks } from "openclaw/plugin-sdk/test-env";
import { installPinnedHostnameTestHooks } from "openclaw/plugin-sdk/test-media-understanding";
import { afterEach, describe, expect, it, vi } from "vitest";
import { buildVydraSpeechProvider } from "./speech-provider.js";
@@ -1,6 +1,6 @@
// Vydra tests cover video generation provider plugin behavior.
import { expectExplicitVideoGenerationCapabilities } from "openclaw/plugin-sdk/provider-test-contracts";
import { installPinnedHostnameTestHooks } from "openclaw/plugin-sdk/test-env";
import { installPinnedHostnameTestHooks } from "openclaw/plugin-sdk/test-media-understanding";
import { afterEach, describe, expect, it, vi } from "vitest";
import {
binaryResponse,
+1 -1
View File
@@ -3,7 +3,7 @@ import {
registerProviderPlugin,
requireRegisteredProvider,
} from "openclaw/plugin-sdk/plugin-test-runtime";
import { isLiveTestEnabled } from "openclaw/plugin-sdk/test-env";
import { isLiveTestEnabled } from "openclaw/plugin-sdk/test-live";
import { describe, expect, it } from "vitest";
import plugin from "./index.js";
+12
View File
@@ -54,6 +54,18 @@
"openclaw/plugin-sdk/test-fixtures": [
"../../packages/plugin-sdk/dist/src/plugin-sdk/test-fixtures.d.ts"
],
"openclaw/plugin-sdk/test-live": [
"../../packages/plugin-sdk/dist/src/plugin-sdk/test-live.d.ts"
],
"openclaw/plugin-sdk/test-live-auth": [
"../../packages/plugin-sdk/dist/src/plugin-sdk/test-live-auth.d.ts"
],
"openclaw/plugin-sdk/test-media-generation": [
"../../packages/plugin-sdk/dist/src/plugin-sdk/test-media-generation.d.ts"
],
"openclaw/plugin-sdk/test-media-understanding": [
"../../packages/plugin-sdk/dist/src/plugin-sdk/test-media-understanding.d.ts"
],
"openclaw/plugin-sdk/test-node-mocks": [
"../../packages/plugin-sdk/dist/src/plugin-sdk/test-node-mocks.d.ts"
],
+1 -1
View File
@@ -1,5 +1,5 @@
// Xai tests cover x search plugin behavior.
import { isBillingErrorMessage } from "openclaw/plugin-sdk/test-env";
import { isBillingErrorMessage } from "openclaw/plugin-sdk/test-live";
import { describe, expect, it } from "vitest";
import { createXSearchTool } from "./x-search.js";
+1 -1
View File
@@ -21,7 +21,7 @@ import {
type RealtimeVoiceBridgeEvent,
} from "openclaw/plugin-sdk/realtime-voice";
import { getRuntimeConfig } from "openclaw/plugin-sdk/runtime-config-snapshot";
import { isBillingErrorMessage } from "openclaw/plugin-sdk/test-env";
import { isBillingErrorMessage } from "openclaw/plugin-sdk/test-live";
import { describe, expect, it } from "vitest";
import { createCodeExecutionTool } from "./code-execution.js";
import plugin from "./index.js";
+1 -1
View File
@@ -3,7 +3,7 @@ import {
registerProviderPlugin,
requireRegisteredProvider,
} from "openclaw/plugin-sdk/plugin-test-runtime";
import { isLiveTestEnabled } from "openclaw/plugin-sdk/test-env";
import { isLiveTestEnabled } from "openclaw/plugin-sdk/test-live";
import { describe, expect, it } from "vitest";
import plugin from "./index.js";
+8
View File
@@ -66,6 +66,14 @@
"!dist/plugin-sdk/test-env.d.ts",
"!dist/plugin-sdk/test-fixtures.js",
"!dist/plugin-sdk/test-fixtures.d.ts",
"!dist/plugin-sdk/test-live.js",
"!dist/plugin-sdk/test-live.d.ts",
"!dist/plugin-sdk/test-live-auth.js",
"!dist/plugin-sdk/test-live-auth.d.ts",
"!dist/plugin-sdk/test-media-generation.js",
"!dist/plugin-sdk/test-media-generation.d.ts",
"!dist/plugin-sdk/test-media-understanding.js",
"!dist/plugin-sdk/test-media-understanding.d.ts",
"!dist/plugin-sdk/test-node-mocks.js",
"!dist/plugin-sdk/test-node-mocks.d.ts",
"!dist/plugin-sdk/test-utils.js",
@@ -32,7 +32,7 @@ const FORBIDDEN_PATTERNS: Array<{ pattern: RegExp; hint: string }> = [
},
{
pattern: /["'](?:\.\.\/)+(?:test\/helpers\/media-generation\/)[^"']+["']/,
hint: "Use openclaw/plugin-sdk/provider-test-contracts or openclaw/plugin-sdk/provider-http-test-mocks instead of repo-only media provider helper bridges.",
hint: "Use openclaw/plugin-sdk/test-media-generation, provider-test-contracts, or provider-http-test-mocks instead of repo-only media provider helper bridges.",
},
{
pattern:
+4
View File
@@ -137,6 +137,10 @@
"provider-test-contracts",
"test-env",
"test-fixtures",
"test-live",
"test-live-auth",
"test-media-generation",
"test-media-understanding",
"test-node-mocks",
"temp-path",
"time-runtime",
@@ -19,6 +19,10 @@
"ssrf-runtime-internal",
"test-env",
"test-fixtures",
"test-live",
"test-live-auth",
"test-media-generation",
"test-media-understanding",
"test-node-mocks",
"test-utils"
]
+43
View File
@@ -0,0 +1,43 @@
import { isTruthyEnvValue } from "../infra/env.js";
const LIVE_OK_PROMPT = "Reply with the word ok.";
/** Return whether live tests are enabled by standard or caller-specific env flags. */
export function isLiveTestEnabled(
extraEnvVars: readonly string[] = [],
env: NodeJS.ProcessEnv = process.env,
): boolean {
return [...extraEnvVars, "LIVE", "OPENCLAW_LIVE_TEST"].some((name) =>
isTruthyEnvValue(env[name]),
);
}
/** Return whether live tests must prefer profile credentials over env keys. */
export function isLiveProfileKeyModeEnabled(env: NodeJS.ProcessEnv = process.env): boolean {
return isTruthyEnvValue(env.OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS);
}
/** Build a single user-message prompt for simple live model probes. */
export function createSingleUserPromptMessage(content = LIVE_OK_PROMPT) {
return [
{
role: "user" as const,
content,
timestamp: Date.now(),
},
];
}
/** Extract non-empty assistant text from content blocks. */
export function extractNonEmptyAssistantText(
content: Array<{
type?: string;
text?: string;
}>,
) {
return content
.filter((block) => block.type === "text")
.map((block) => block.text?.trim() ?? "")
.filter(Boolean)
.join(" ");
}
+9 -47
View File
@@ -1,28 +1,19 @@
/**
* Shared helpers for live provider tests and timeout-wrapped completions.
*/
import { isTruthyEnvValue } from "../infra/env.js";
import { completeSimple } from "../llm/stream.js";
import type { Api, Model } from "../llm/types.js";
// Shared live-test helpers. Live lanes opt in via env flags and use guarded
// model calls so missing credentials skip cleanly instead of hanging tests.
const LIVE_OK_PROMPT = "Reply with the word ok.";
export {
createSingleUserPromptMessage,
extractNonEmptyAssistantText,
isLiveProfileKeyModeEnabled,
isLiveTestEnabled,
} from "./live-test-config.js";
/** Return whether live tests are enabled by standard or caller-specific env flags. */
export function isLiveTestEnabled(
extraEnvVars: readonly string[] = [],
env: NodeJS.ProcessEnv = process.env,
): boolean {
return [...extraEnvVars, "LIVE", "OPENCLAW_LIVE_TEST"].some((name) =>
isTruthyEnvValue(env[name]),
);
}
/** Return whether live tests must prefer profile credentials over env keys. */
export function isLiveProfileKeyModeEnabled(env: NodeJS.ProcessEnv = process.env): boolean {
return isTruthyEnvValue(env.OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS);
}
export type CompleteSimpleContent<TApi extends Api = Api> = Awaited<
ReturnType<typeof completeSimple<TApi>>
>["content"];
/** Return whether a provider requires profile credentials in the current live mode. */
export function requiresLiveProfileCredential(
@@ -42,35 +33,6 @@ export function resolveLiveCredentialPrecedence(
: "env-first";
}
/** Build a single user-message prompt for simple live model probes. */
export function createSingleUserPromptMessage(content = LIVE_OK_PROMPT) {
return [
{
role: "user" as const,
content,
timestamp: Date.now(),
},
];
}
/** Extract non-empty assistant text from content blocks. */
export function extractNonEmptyAssistantText(
content: Array<{
type?: string;
text?: string;
}>,
) {
return content
.filter((block) => block.type === "text")
.map((block) => block.text?.trim() ?? "")
.filter(Boolean)
.join(" ");
}
export type CompleteSimpleContent<TApi extends Api = Api> = Awaited<
ReturnType<typeof completeSimple<TApi>>
>["content"];
/** Write a namespaced live-test progress line to stderr. */
export function logLiveProgress(message: string): void {
process.stderr.write(`[live] ${message}\n`);
@@ -18,7 +18,7 @@ import {
isBillingErrorMessage,
isOverloadedErrorMessage,
isServerErrorMessage,
} from "../../plugin-sdk/test-env.js";
} from "../embedded-agent-helpers/failover-matches.js";
import { isLiveTestEnabled } from "../live-test-helpers.js";
import { isLiveAuthDrift } from "../live-test-provider-drift.test-support.js";
import { createImageTool } from "./image-tool.js";
+8
View File
@@ -59,6 +59,14 @@ const OMITTED_PLUGIN_SDK_TEST_FILES = new Set([
"dist/plugin-sdk/test-env.js",
"dist/plugin-sdk/test-fixtures.d.ts",
"dist/plugin-sdk/test-fixtures.js",
"dist/plugin-sdk/test-live.d.ts",
"dist/plugin-sdk/test-live.js",
"dist/plugin-sdk/test-live-auth.d.ts",
"dist/plugin-sdk/test-live-auth.js",
"dist/plugin-sdk/test-media-generation.d.ts",
"dist/plugin-sdk/test-media-generation.js",
"dist/plugin-sdk/test-media-understanding.d.ts",
"dist/plugin-sdk/test-media-understanding.js",
"dist/plugin-sdk/test-node-mocks.d.ts",
"dist/plugin-sdk/test-node-mocks.js",
]);
+1 -53
View File
@@ -1,56 +1,4 @@
// Focused public test helpers for environment, network, and time fixtures.
export {
createAuthCaptureJsonFetch,
createRequestCaptureJsonFetch,
installPinnedHostnameTestHooks,
} from "../media-understanding/audio.test-helpers.ts";
export {
createSingleUserPromptMessage,
extractNonEmptyAssistantText,
isLiveProfileKeyModeEnabled,
isLiveTestEnabled,
} from "../agents/live-test-helpers.js";
export { collectProviderApiKeys } from "../agents/live-auth-keys.js";
export { isModelNotFoundErrorMessage } from "../agents/live-model-errors.js";
export {
isAuthErrorMessage,
isBillingErrorMessage,
isOverloadedErrorMessage,
isServerErrorMessage,
isTimeoutErrorMessage,
} from "../agents/embedded-agent-helpers/failover-matches.js";
export { maybeLoadShellEnvForGenerationProviders } from "../test-utils/generation-live-test-helpers.js";
export { isTruthyEnvValue } from "../infra/env.js";
export { getShellEnvAppliedKeys } from "../infra/shell-env.js";
export { encodePngRgba, fillPixel } from "../media/png-encode.js";
export {
parseLiveCsvFilter as parseCsvFilter,
parseProviderModelMap,
redactLiveApiKey,
} from "../media-generation/live-test-helpers.js";
export {
DEFAULT_LIVE_MUSIC_MODELS,
resolveConfiguredLiveMusicModels,
resolveLiveMusicAuthStore,
} from "../music-generation/live-test-helpers.js";
export {
canRunBufferBackedImageToVideoLiveLane,
canRunBufferBackedVideoToVideoLiveLane,
DEFAULT_LIVE_VIDEO_MODELS,
resolveConfiguredLiveVideoModels,
resolveLiveVideoAuthStore,
resolveLiveVideoResolution,
} from "../video-generation/live-test-helpers.js";
export { normalizeVideoGenerationDuration } from "../video-generation/duration-support.js";
export { parseVideoGenerationModelRef } from "../video-generation/model-ref.js";
export type {
GeneratedVideoAsset,
VideoGenerationMode,
VideoGenerationModeCapabilities,
VideoGenerationProvider,
VideoGenerationRequest,
} from "../video-generation/types.js";
// Repo-local helpers for environment, network, filesystem, and time fixtures.
export { jsonResponse, requestBodyText, requestUrl } from "../test-helpers/http.js";
export { mockPinnedHostnameResolution } from "../test-helpers/ssrf.js";
export { createWindowsCmdShimFixture } from "../test-helpers/windows-cmd-shim.js";
+5
View File
@@ -0,0 +1,5 @@
// Repo-local helpers for live-test credential discovery and shell environment loading.
export { collectProviderApiKeys } from "../agents/live-auth-keys.js";
export { getShellEnvAppliedKeys } from "../infra/shell-env.js";
export { maybeLoadShellEnvForGenerationProviders } from "../test-utils/generation-live-test-helpers.js";
+17
View File
@@ -0,0 +1,17 @@
// Repo-local helpers for live-test gating, prompts, and provider error classification.
export {
createSingleUserPromptMessage,
extractNonEmptyAssistantText,
isLiveProfileKeyModeEnabled,
isLiveTestEnabled,
} from "../agents/live-test-config.js";
export { isModelNotFoundErrorMessage } from "../agents/live-model-errors.js";
export {
isAuthErrorMessage,
isBillingErrorMessage,
isOverloadedErrorMessage,
isServerErrorMessage,
isTimeoutErrorMessage,
} from "../agents/embedded-agent-helpers/failover-matches.js";
export { isTruthyEnvValue } from "../infra/env.js";
+30
View File
@@ -0,0 +1,30 @@
// Repo-local helpers for music, image, and video generation tests.
export { encodePngRgba, fillPixel } from "../media/png-encode.js";
export {
parseLiveCsvFilter as parseCsvFilter,
parseProviderModelMap,
redactLiveApiKey,
} from "../media-generation/live-test-helpers.js";
export {
DEFAULT_LIVE_MUSIC_MODELS,
resolveConfiguredLiveMusicModels,
resolveLiveMusicAuthStore,
} from "../music-generation/live-test-helpers.js";
export {
canRunBufferBackedImageToVideoLiveLane,
canRunBufferBackedVideoToVideoLiveLane,
DEFAULT_LIVE_VIDEO_MODELS,
resolveConfiguredLiveVideoModels,
resolveLiveVideoAuthStore,
resolveLiveVideoResolution,
} from "../video-generation/live-test-helpers.js";
export { normalizeVideoGenerationDuration } from "../video-generation/duration-support.js";
export { parseVideoGenerationModelRef } from "../video-generation/model-ref.js";
export type {
GeneratedVideoAsset,
VideoGenerationMode,
VideoGenerationModeCapabilities,
VideoGenerationProvider,
VideoGenerationRequest,
} from "../video-generation/types.js";
@@ -0,0 +1,7 @@
// Repo-local request-capture helpers for media-understanding provider tests.
export {
createAuthCaptureJsonFetch,
createRequestCaptureJsonFetch,
installPinnedHostnameTestHooks,
} from "../media-understanding/audio.test-helpers.ts";
@@ -80,6 +80,10 @@ const PUBLIC_SDK_TEST_HELPER_SUBPATHS = [
"provider-test-contracts",
"test-env",
"test-fixtures",
"test-live",
"test-live-auth",
"test-media-generation",
"test-media-understanding",
"test-node-mocks",
] as const;
const PUBLIC_SDK_TEST_HELPER_SUBPATHS_WITH_TOP_LEVEL_MOCKS = ["provider-http-test-mocks"] as const;
@@ -817,9 +821,33 @@ describe("plugin-sdk subpath exports", () => {
"withTempHome",
"createMockIncomingRequest",
"withFetchPreconnect",
]);
expectSourceOmits("test-env", [
"collectProviderApiKeys",
"createRequestCaptureJsonFetch",
"isLiveTestEnabled",
"resolveConfiguredLiveVideoModels",
]);
expectSourceMentions("test-live", [
"createSingleUserPromptMessage",
"isLiveTestEnabled",
"isBillingErrorMessage",
"isModelNotFoundErrorMessage",
]);
expectSourceMentions("test-live-auth", [
"collectProviderApiKeys",
"getShellEnvAppliedKeys",
"maybeLoadShellEnvForGenerationProviders",
]);
expectSourceMentions("test-media-understanding", [
"createRequestCaptureJsonFetch",
"installPinnedHostnameTestHooks",
"isLiveTestEnabled",
]);
expectSourceMentions("test-media-generation", [
"encodePngRgba",
"parseProviderModelMap",
"resolveConfiguredLiveMusicModels",
"resolveConfiguredLiveVideoModels",
]);
expectSourceMentions("test-fixtures", [
"createCliRuntimeCapture",