mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-04 02:20:26 +00:00
perf: reduce unit test hot path overhead
This commit is contained in:
@@ -5,11 +5,10 @@ import type {
|
||||
SetSessionConfigOptionRequest,
|
||||
SetSessionModeRequest,
|
||||
} from "@agentclientprotocol/sdk";
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import { listThinkingLevels } from "../auto-reply/thinking.js";
|
||||
import type { GatewayClient } from "../gateway/client.js";
|
||||
import type { EventFrame } from "../gateway/protocol/index.js";
|
||||
import { resetProviderRuntimeHookCacheForTest } from "../plugins/provider-runtime.js";
|
||||
import { createInMemorySessionStore } from "./session.js";
|
||||
import { AcpGatewayAgent } from "./translator.js";
|
||||
import { createAcpConnection, createAcpGateway } from "./translator.test-helpers.js";
|
||||
@@ -121,10 +120,6 @@ async function expectOversizedPromptRejected(params: { sessionId: string; text:
|
||||
sessionStore.clearAllSessionsForTest();
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
resetProviderRuntimeHookCacheForTest();
|
||||
});
|
||||
|
||||
describe("acp session creation rate limit", () => {
|
||||
it("rate limits excessive newSession bursts", async () => {
|
||||
const sessionStore = createInMemorySessionStore();
|
||||
|
||||
@@ -14,6 +14,25 @@ export type ThinkingCatalogEntry = {
|
||||
const BASE_THINKING_LEVELS: ThinkLevel[] = ["off", "minimal", "low", "medium", "high", "adaptive"];
|
||||
const ANTHROPIC_CLAUDE_46_MODEL_RE = /^claude-(?:opus|sonnet)-4(?:\.|-)6(?:$|[-.])/i;
|
||||
const AMAZON_BEDROCK_CLAUDE_46_MODEL_RE = /claude-(?:opus|sonnet)-4(?:\.|-)6(?:$|[-.])/i;
|
||||
const OPENAI_XHIGH_MODEL_IDS = [
|
||||
"gpt-5.4",
|
||||
"gpt-5.4-pro",
|
||||
"gpt-5.4-mini",
|
||||
"gpt-5.4-nano",
|
||||
"gpt-5.2",
|
||||
] as const;
|
||||
const OPENAI_CODEX_XHIGH_MODEL_IDS = [
|
||||
"gpt-5.4",
|
||||
"gpt-5.3-codex",
|
||||
"gpt-5.3-codex-spark",
|
||||
"gpt-5.2-codex",
|
||||
"gpt-5.1-codex",
|
||||
] as const;
|
||||
const GITHUB_COPILOT_XHIGH_MODEL_IDS = ["gpt-5.2", "gpt-5.2-codex"] as const;
|
||||
|
||||
function matchesExactOrPrefix(modelId: string, ids: readonly string[]): boolean {
|
||||
return ids.some((candidate) => modelId === candidate || modelId.startsWith(`${candidate}-`));
|
||||
}
|
||||
|
||||
export function normalizeProviderId(provider?: string | null): string {
|
||||
if (!provider) {
|
||||
@@ -33,6 +52,27 @@ export function isBinaryThinkingProvider(provider?: string | null): boolean {
|
||||
return normalizeProviderId(provider) === "zai";
|
||||
}
|
||||
|
||||
export function supportsBuiltInXHighThinking(
|
||||
provider?: string | null,
|
||||
model?: string | null,
|
||||
): boolean {
|
||||
const providerId = normalizeProviderId(provider);
|
||||
const modelId = model?.trim().toLowerCase();
|
||||
if (!providerId || !modelId) {
|
||||
return false;
|
||||
}
|
||||
if (providerId === "openai") {
|
||||
return matchesExactOrPrefix(modelId, OPENAI_XHIGH_MODEL_IDS);
|
||||
}
|
||||
if (providerId === "openai-codex") {
|
||||
return matchesExactOrPrefix(modelId, OPENAI_CODEX_XHIGH_MODEL_IDS);
|
||||
}
|
||||
if (providerId === "github-copilot") {
|
||||
return GITHUB_COPILOT_XHIGH_MODEL_IDS.includes(modelId as never);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Normalize user-provided thinking level strings to the canonical enum.
|
||||
export function normalizeThinkLevel(raw?: string | null): ThinkLevel | undefined {
|
||||
if (!raw) {
|
||||
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
listThinkingLevels as listThinkingLevelsFallback,
|
||||
normalizeProviderId,
|
||||
resolveThinkingDefaultForModel as resolveThinkingDefaultForModelFallback,
|
||||
supportsBuiltInXHighThinking,
|
||||
} from "./thinking.shared.js";
|
||||
import type { ThinkLevel, ThinkingCatalogEntry } from "./thinking.shared.js";
|
||||
export {
|
||||
@@ -36,6 +37,9 @@ import {
|
||||
} from "../plugins/provider-runtime.js";
|
||||
|
||||
export function isBinaryThinkingProvider(provider?: string | null, model?: string | null): boolean {
|
||||
if (isBinaryThinkingProviderFallback(provider)) {
|
||||
return true;
|
||||
}
|
||||
const normalizedProvider = normalizeProviderId(provider);
|
||||
if (!normalizedProvider) {
|
||||
return false;
|
||||
@@ -59,6 +63,9 @@ export function supportsXHighThinking(provider?: string | null, model?: string |
|
||||
if (!modelKey) {
|
||||
return false;
|
||||
}
|
||||
if (supportsBuiltInXHighThinking(provider, modelKey)) {
|
||||
return true;
|
||||
}
|
||||
const providerKey = normalizeProviderId(provider);
|
||||
if (providerKey) {
|
||||
const pluginDecision = resolveProviderXHighThinking({
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
import { matrixPlugin } from "../../extensions/matrix/index.js";
|
||||
import { msteamsPlugin } from "../../extensions/msteams/index.js";
|
||||
import { nostrPlugin } from "../../extensions/nostr/index.js";
|
||||
import { tlonPlugin } from "../../extensions/tlon/index.js";
|
||||
import { bundledChannelPlugins } from "../channels/plugins/bundled.js";
|
||||
import { setActivePluginRegistry } from "../plugins/runtime.js";
|
||||
import { createTestRegistry } from "../test-utils/channel-plugins.js";
|
||||
@@ -20,7 +24,13 @@ type PatchedSetupAdapterFields = {
|
||||
};
|
||||
|
||||
export function setDefaultChannelPluginRegistryForTests(): void {
|
||||
const channels = bundledChannelPlugins.map((plugin) => ({
|
||||
const channels = [
|
||||
...bundledChannelPlugins,
|
||||
matrixPlugin,
|
||||
msteamsPlugin,
|
||||
nostrPlugin,
|
||||
tlonPlugin,
|
||||
].map((plugin) => ({
|
||||
pluginId: plugin.id,
|
||||
plugin,
|
||||
source: "test" as const,
|
||||
|
||||
@@ -1,9 +1,18 @@
|
||||
import fs from "node:fs/promises";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
import { afterAll, beforeAll, describe, expect, it } from "vitest";
|
||||
import { afterAll, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { NON_ENV_SECRETREF_MARKER } from "../agents/model-auth-markers.js";
|
||||
import { resolveProviderAuths, type ProviderAuth } from "./provider-usage.auth.js";
|
||||
|
||||
const resolveProviderUsageAuthWithPluginMock = vi.fn(async () => null);
|
||||
|
||||
vi.mock("../plugins/provider-runtime.js", () => ({
|
||||
resolveProviderUsageAuthWithPlugin: (...args: unknown[]) =>
|
||||
resolveProviderUsageAuthWithPluginMock(...args),
|
||||
}));
|
||||
|
||||
let resolveProviderAuths: typeof import("./provider-usage.auth.js").resolveProviderAuths;
|
||||
type ProviderAuth = import("./provider-usage.auth.js").ProviderAuth;
|
||||
|
||||
describe("resolveProviderAuths key normalization", () => {
|
||||
let suiteRoot = "";
|
||||
@@ -18,6 +27,7 @@ describe("resolveProviderAuths key normalization", () => {
|
||||
|
||||
beforeAll(async () => {
|
||||
suiteRoot = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-provider-auth-suite-"));
|
||||
({ resolveProviderAuths } = await import("./provider-usage.auth.js"));
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
@@ -26,6 +36,11 @@ describe("resolveProviderAuths key normalization", () => {
|
||||
suiteCase = 0;
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
resolveProviderUsageAuthWithPluginMock.mockReset();
|
||||
resolveProviderUsageAuthWithPluginMock.mockResolvedValue(null);
|
||||
});
|
||||
|
||||
async function withSuiteHome<T>(
|
||||
fn: (home: string) => Promise<T>,
|
||||
env: Record<string, string | undefined>,
|
||||
|
||||
@@ -229,17 +229,19 @@ export async function resolveProviderAuths(params: {
|
||||
providers: UsageProviderId[];
|
||||
auth?: ProviderAuth[];
|
||||
agentDir?: string;
|
||||
config?: OpenClawConfig;
|
||||
env?: NodeJS.ProcessEnv;
|
||||
}): Promise<ProviderAuth[]> {
|
||||
if (params.auth) {
|
||||
return params.auth;
|
||||
}
|
||||
|
||||
const state: UsageAuthState = {
|
||||
cfg: loadConfig(),
|
||||
cfg: params.config ?? loadConfig(),
|
||||
store: ensureAuthProfileStore(params.agentDir, {
|
||||
allowKeychainPrompt: false,
|
||||
}),
|
||||
env: process.env,
|
||||
env: params.env ?? process.env,
|
||||
agentDir: params.agentDir,
|
||||
};
|
||||
const auths: ProviderAuth[] = [];
|
||||
|
||||
@@ -179,6 +179,8 @@ export async function loadProviderUsageSummary(
|
||||
providers: opts.providers ?? usageProviders,
|
||||
auth: opts.auth,
|
||||
agentDir: opts.agentDir,
|
||||
config,
|
||||
env,
|
||||
});
|
||||
if (auths.length === 0) {
|
||||
return { updatedAt: now, providers: [] };
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import { createProviderUsageFetch } from "../test-utils/provider-usage-fetch.js";
|
||||
import type { ProviderAuth } from "./provider-usage.auth.js";
|
||||
import type { UsageSummary } from "./provider-usage.types.js";
|
||||
@@ -8,6 +9,7 @@ type ProviderUsageLoader = (params: {
|
||||
now: number;
|
||||
auth?: ProviderAuth[];
|
||||
fetch?: typeof fetch;
|
||||
config?: OpenClawConfig;
|
||||
}) => Promise<UsageSummary>;
|
||||
|
||||
export type ProviderUsageAuth<T extends ProviderUsageLoader> = NonNullable<
|
||||
@@ -23,5 +25,7 @@ export async function loadUsageWithAuth<T extends ProviderUsageLoader>(
|
||||
now: usageNow,
|
||||
auth,
|
||||
fetch: mockFetch as unknown as typeof fetch,
|
||||
// These tests exercise the built-in usage fetchers, not provider plugin hooks.
|
||||
config: { plugins: { enabled: false } } as OpenClawConfig,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -294,6 +294,7 @@ describe("provider usage loading", () => {
|
||||
providers: ["anthropic"],
|
||||
agentDir,
|
||||
fetch: mockFetch as unknown as typeof fetch,
|
||||
config: { plugins: { enabled: false } },
|
||||
});
|
||||
|
||||
const claude = expectSingleAnthropicProvider(summary);
|
||||
|
||||
@@ -2,7 +2,7 @@ import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
const loadWebMediaMock = vi.hoisted(() => vi.fn());
|
||||
|
||||
vi.mock("../media/web-media.js", () => ({
|
||||
vi.mock("./web-media.js", () => ({
|
||||
loadWebMedia: loadWebMediaMock,
|
||||
}));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user