mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 09:10:45 +00:00
perf(test): slim codex web search test imports
This commit is contained in:
194
src/agents/codex-native-web-search-core.ts
Normal file
194
src/agents/codex-native-web-search-core.ts
Normal file
@@ -0,0 +1,194 @@
|
||||
import type { OpenClawConfig } from "../config/types.openclaw.js";
|
||||
import { isRecord } from "../utils.js";
|
||||
import { listProfilesForProvider } from "./auth-profiles/profile-list.js";
|
||||
import { ensureAuthProfileStore } from "./auth-profiles/store.js";
|
||||
import {
|
||||
type CodexNativeSearchMode,
|
||||
resolveCodexNativeWebSearchConfig,
|
||||
} from "./codex-native-web-search.shared.js";
|
||||
|
||||
export type CodexNativeSearchActivation = {
|
||||
globalWebSearchEnabled: boolean;
|
||||
codexNativeEnabled: boolean;
|
||||
codexMode: CodexNativeSearchMode;
|
||||
nativeEligible: boolean;
|
||||
hasRequiredAuth: boolean;
|
||||
state: "managed_only" | "native_active";
|
||||
inactiveReason?:
|
||||
| "globally_disabled"
|
||||
| "codex_not_enabled"
|
||||
| "model_not_eligible"
|
||||
| "codex_auth_missing";
|
||||
};
|
||||
|
||||
export type CodexNativeSearchPayloadPatchResult = {
|
||||
status: "payload_not_object" | "native_tool_already_present" | "injected";
|
||||
};
|
||||
|
||||
export function isCodexNativeSearchEligibleModel(params: {
|
||||
modelProvider?: string;
|
||||
modelApi?: string;
|
||||
}): boolean {
|
||||
return params.modelProvider === "openai-codex" || params.modelApi === "openai-codex-responses";
|
||||
}
|
||||
|
||||
export function hasCodexNativeWebSearchTool(tools: unknown): boolean {
|
||||
if (!Array.isArray(tools)) {
|
||||
return false;
|
||||
}
|
||||
return tools.some(
|
||||
(tool) => isRecord(tool) && typeof tool.type === "string" && tool.type === "web_search",
|
||||
);
|
||||
}
|
||||
|
||||
export function hasAvailableCodexAuth(params: {
|
||||
config?: OpenClawConfig;
|
||||
agentDir?: string;
|
||||
}): boolean {
|
||||
if (
|
||||
Object.values(params.config?.auth?.profiles ?? {}).some(
|
||||
(profile) => isRecord(profile) && profile.provider === "openai-codex",
|
||||
)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (params.agentDir) {
|
||||
try {
|
||||
if (
|
||||
listProfilesForProvider(ensureAuthProfileStore(params.agentDir), "openai-codex").length > 0
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
} catch {
|
||||
// Fall back to config-based detection below.
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
export function resolveCodexNativeSearchActivation(params: {
|
||||
config?: OpenClawConfig;
|
||||
modelProvider?: string;
|
||||
modelApi?: string;
|
||||
agentDir?: string;
|
||||
}): CodexNativeSearchActivation {
|
||||
const globalWebSearchEnabled = params.config?.tools?.web?.search?.enabled !== false;
|
||||
const codexConfig = resolveCodexNativeWebSearchConfig(params.config);
|
||||
const nativeEligible = isCodexNativeSearchEligibleModel(params);
|
||||
const hasRequiredAuth = params.modelProvider !== "openai-codex" || hasAvailableCodexAuth(params);
|
||||
|
||||
if (!globalWebSearchEnabled) {
|
||||
return {
|
||||
globalWebSearchEnabled,
|
||||
codexNativeEnabled: codexConfig.enabled,
|
||||
codexMode: codexConfig.mode,
|
||||
nativeEligible,
|
||||
hasRequiredAuth,
|
||||
state: "managed_only",
|
||||
inactiveReason: "globally_disabled",
|
||||
};
|
||||
}
|
||||
|
||||
if (!codexConfig.enabled) {
|
||||
return {
|
||||
globalWebSearchEnabled,
|
||||
codexNativeEnabled: false,
|
||||
codexMode: codexConfig.mode,
|
||||
nativeEligible,
|
||||
hasRequiredAuth,
|
||||
state: "managed_only",
|
||||
inactiveReason: "codex_not_enabled",
|
||||
};
|
||||
}
|
||||
|
||||
if (!nativeEligible) {
|
||||
return {
|
||||
globalWebSearchEnabled,
|
||||
codexNativeEnabled: true,
|
||||
codexMode: codexConfig.mode,
|
||||
nativeEligible: false,
|
||||
hasRequiredAuth,
|
||||
state: "managed_only",
|
||||
inactiveReason: "model_not_eligible",
|
||||
};
|
||||
}
|
||||
|
||||
if (!hasRequiredAuth) {
|
||||
return {
|
||||
globalWebSearchEnabled,
|
||||
codexNativeEnabled: true,
|
||||
codexMode: codexConfig.mode,
|
||||
nativeEligible: true,
|
||||
hasRequiredAuth: false,
|
||||
state: "managed_only",
|
||||
inactiveReason: "codex_auth_missing",
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
globalWebSearchEnabled,
|
||||
codexNativeEnabled: true,
|
||||
codexMode: codexConfig.mode,
|
||||
nativeEligible: true,
|
||||
hasRequiredAuth: true,
|
||||
state: "native_active",
|
||||
};
|
||||
}
|
||||
|
||||
export function buildCodexNativeWebSearchTool(
|
||||
config: OpenClawConfig | undefined,
|
||||
): Record<string, unknown> {
|
||||
const nativeConfig = resolveCodexNativeWebSearchConfig(config);
|
||||
const tool: Record<string, unknown> = {
|
||||
type: "web_search",
|
||||
external_web_access: nativeConfig.mode === "live",
|
||||
};
|
||||
|
||||
if (nativeConfig.allowedDomains) {
|
||||
tool.filters = {
|
||||
allowed_domains: nativeConfig.allowedDomains,
|
||||
};
|
||||
}
|
||||
|
||||
if (nativeConfig.contextSize) {
|
||||
tool.search_context_size = nativeConfig.contextSize;
|
||||
}
|
||||
|
||||
if (nativeConfig.userLocation) {
|
||||
tool.user_location = {
|
||||
type: "approximate",
|
||||
...nativeConfig.userLocation,
|
||||
};
|
||||
}
|
||||
|
||||
return tool;
|
||||
}
|
||||
|
||||
export function patchCodexNativeWebSearchPayload(params: {
|
||||
payload: unknown;
|
||||
config?: OpenClawConfig;
|
||||
}): CodexNativeSearchPayloadPatchResult {
|
||||
if (!isRecord(params.payload)) {
|
||||
return { status: "payload_not_object" };
|
||||
}
|
||||
|
||||
const payload = params.payload;
|
||||
if (hasCodexNativeWebSearchTool(payload.tools)) {
|
||||
return { status: "native_tool_already_present" };
|
||||
}
|
||||
|
||||
const tools = Array.isArray(payload.tools) ? [...payload.tools] : [];
|
||||
tools.push(buildCodexNativeWebSearchTool(params.config));
|
||||
payload.tools = tools;
|
||||
return { status: "injected" };
|
||||
}
|
||||
|
||||
export function shouldSuppressManagedWebSearchTool(params: {
|
||||
config?: OpenClawConfig;
|
||||
modelProvider?: string;
|
||||
modelApi?: string;
|
||||
agentDir?: string;
|
||||
}): boolean {
|
||||
return resolveCodexNativeSearchActivation(params).state === "native_active";
|
||||
}
|
||||
@@ -1,9 +1,21 @@
|
||||
import type { OpenClawConfig } from "../config/types.openclaw.js";
|
||||
import { isRecord } from "../utils.js";
|
||||
import { ensureAuthProfileStore, listProfilesForProvider } from "./auth-profiles.js";
|
||||
import {
|
||||
hasAvailableCodexAuth,
|
||||
isCodexNativeSearchEligibleModel,
|
||||
} from "./codex-native-web-search-core.js";
|
||||
import { resolveCodexNativeWebSearchConfig } from "./codex-native-web-search.shared.js";
|
||||
import type { CodexNativeSearchMode } from "./codex-native-web-search.shared.js";
|
||||
import { resolveDefaultModelForAgent } from "./model-selection.js";
|
||||
export {
|
||||
buildCodexNativeWebSearchTool,
|
||||
type CodexNativeSearchActivation,
|
||||
type CodexNativeSearchPayloadPatchResult,
|
||||
hasAvailableCodexAuth,
|
||||
hasCodexNativeWebSearchTool,
|
||||
isCodexNativeSearchEligibleModel,
|
||||
patchCodexNativeWebSearchPayload,
|
||||
resolveCodexNativeSearchActivation,
|
||||
shouldSuppressManagedWebSearchTool,
|
||||
} from "./codex-native-web-search-core.js";
|
||||
export {
|
||||
type CodexNativeSearchContextSize,
|
||||
type CodexNativeSearchMode,
|
||||
@@ -13,192 +25,6 @@ export {
|
||||
resolveCodexNativeWebSearchConfig,
|
||||
} from "./codex-native-web-search.shared.js";
|
||||
|
||||
export type CodexNativeSearchActivation = {
|
||||
globalWebSearchEnabled: boolean;
|
||||
codexNativeEnabled: boolean;
|
||||
codexMode: CodexNativeSearchMode;
|
||||
nativeEligible: boolean;
|
||||
hasRequiredAuth: boolean;
|
||||
state: "managed_only" | "native_active";
|
||||
inactiveReason?:
|
||||
| "globally_disabled"
|
||||
| "codex_not_enabled"
|
||||
| "model_not_eligible"
|
||||
| "codex_auth_missing";
|
||||
};
|
||||
|
||||
export type CodexNativeSearchPayloadPatchResult = {
|
||||
status: "payload_not_object" | "native_tool_already_present" | "injected";
|
||||
};
|
||||
|
||||
export function isCodexNativeSearchEligibleModel(params: {
|
||||
modelProvider?: string;
|
||||
modelApi?: string;
|
||||
}): boolean {
|
||||
return params.modelProvider === "openai-codex" || params.modelApi === "openai-codex-responses";
|
||||
}
|
||||
|
||||
export function hasCodexNativeWebSearchTool(tools: unknown): boolean {
|
||||
if (!Array.isArray(tools)) {
|
||||
return false;
|
||||
}
|
||||
return tools.some(
|
||||
(tool) => isRecord(tool) && typeof tool.type === "string" && tool.type === "web_search",
|
||||
);
|
||||
}
|
||||
|
||||
export function hasAvailableCodexAuth(params: {
|
||||
config?: OpenClawConfig;
|
||||
agentDir?: string;
|
||||
}): boolean {
|
||||
if (
|
||||
Object.values(params.config?.auth?.profiles ?? {}).some(
|
||||
(profile) => isRecord(profile) && profile.provider === "openai-codex",
|
||||
)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (params.agentDir) {
|
||||
try {
|
||||
if (
|
||||
listProfilesForProvider(ensureAuthProfileStore(params.agentDir), "openai-codex").length > 0
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
} catch {
|
||||
// Fall back to config-based detection below.
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
export function resolveCodexNativeSearchActivation(params: {
|
||||
config?: OpenClawConfig;
|
||||
modelProvider?: string;
|
||||
modelApi?: string;
|
||||
agentDir?: string;
|
||||
}): CodexNativeSearchActivation {
|
||||
const globalWebSearchEnabled = params.config?.tools?.web?.search?.enabled !== false;
|
||||
const codexConfig = resolveCodexNativeWebSearchConfig(params.config);
|
||||
const nativeEligible = isCodexNativeSearchEligibleModel(params);
|
||||
const hasRequiredAuth = params.modelProvider !== "openai-codex" || hasAvailableCodexAuth(params);
|
||||
|
||||
if (!globalWebSearchEnabled) {
|
||||
return {
|
||||
globalWebSearchEnabled,
|
||||
codexNativeEnabled: codexConfig.enabled,
|
||||
codexMode: codexConfig.mode,
|
||||
nativeEligible,
|
||||
hasRequiredAuth,
|
||||
state: "managed_only",
|
||||
inactiveReason: "globally_disabled",
|
||||
};
|
||||
}
|
||||
|
||||
if (!codexConfig.enabled) {
|
||||
return {
|
||||
globalWebSearchEnabled,
|
||||
codexNativeEnabled: false,
|
||||
codexMode: codexConfig.mode,
|
||||
nativeEligible,
|
||||
hasRequiredAuth,
|
||||
state: "managed_only",
|
||||
inactiveReason: "codex_not_enabled",
|
||||
};
|
||||
}
|
||||
|
||||
if (!nativeEligible) {
|
||||
return {
|
||||
globalWebSearchEnabled,
|
||||
codexNativeEnabled: true,
|
||||
codexMode: codexConfig.mode,
|
||||
nativeEligible: false,
|
||||
hasRequiredAuth,
|
||||
state: "managed_only",
|
||||
inactiveReason: "model_not_eligible",
|
||||
};
|
||||
}
|
||||
|
||||
if (!hasRequiredAuth) {
|
||||
return {
|
||||
globalWebSearchEnabled,
|
||||
codexNativeEnabled: true,
|
||||
codexMode: codexConfig.mode,
|
||||
nativeEligible: true,
|
||||
hasRequiredAuth: false,
|
||||
state: "managed_only",
|
||||
inactiveReason: "codex_auth_missing",
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
globalWebSearchEnabled,
|
||||
codexNativeEnabled: true,
|
||||
codexMode: codexConfig.mode,
|
||||
nativeEligible: true,
|
||||
hasRequiredAuth: true,
|
||||
state: "native_active",
|
||||
};
|
||||
}
|
||||
|
||||
export function buildCodexNativeWebSearchTool(
|
||||
config: OpenClawConfig | undefined,
|
||||
): Record<string, unknown> {
|
||||
const nativeConfig = resolveCodexNativeWebSearchConfig(config);
|
||||
const tool: Record<string, unknown> = {
|
||||
type: "web_search",
|
||||
external_web_access: nativeConfig.mode === "live",
|
||||
};
|
||||
|
||||
if (nativeConfig.allowedDomains) {
|
||||
tool.filters = {
|
||||
allowed_domains: nativeConfig.allowedDomains,
|
||||
};
|
||||
}
|
||||
|
||||
if (nativeConfig.contextSize) {
|
||||
tool.search_context_size = nativeConfig.contextSize;
|
||||
}
|
||||
|
||||
if (nativeConfig.userLocation) {
|
||||
tool.user_location = {
|
||||
type: "approximate",
|
||||
...nativeConfig.userLocation,
|
||||
};
|
||||
}
|
||||
|
||||
return tool;
|
||||
}
|
||||
|
||||
export function patchCodexNativeWebSearchPayload(params: {
|
||||
payload: unknown;
|
||||
config?: OpenClawConfig;
|
||||
}): CodexNativeSearchPayloadPatchResult {
|
||||
if (!isRecord(params.payload)) {
|
||||
return { status: "payload_not_object" };
|
||||
}
|
||||
|
||||
const payload = params.payload;
|
||||
if (hasCodexNativeWebSearchTool(payload.tools)) {
|
||||
return { status: "native_tool_already_present" };
|
||||
}
|
||||
|
||||
const tools = Array.isArray(payload.tools) ? [...payload.tools] : [];
|
||||
tools.push(buildCodexNativeWebSearchTool(params.config));
|
||||
payload.tools = tools;
|
||||
return { status: "injected" };
|
||||
}
|
||||
|
||||
export function shouldSuppressManagedWebSearchTool(params: {
|
||||
config?: OpenClawConfig;
|
||||
modelProvider?: string;
|
||||
modelApi?: string;
|
||||
agentDir?: string;
|
||||
}): boolean {
|
||||
return resolveCodexNativeSearchActivation(params).state === "native_active";
|
||||
}
|
||||
|
||||
export function isCodexNativeWebSearchRelevant(params: {
|
||||
config: OpenClawConfig;
|
||||
agentId?: string;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { Model } from "@mariozechner/pi-ai";
|
||||
import type { StreamFn } from "@mariozechner/pi-agent-core";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { runExtraParamsCase } from "./extra-params.test-support.js";
|
||||
import { createOpenRouterSystemCacheWrapper } from "./proxy-stream-wrappers.js";
|
||||
|
||||
type StreamPayload = {
|
||||
messages: Array<{
|
||||
@@ -10,24 +10,20 @@ type StreamPayload = {
|
||||
};
|
||||
|
||||
function runOpenRouterPayload(payload: StreamPayload, modelId: string) {
|
||||
runExtraParamsCase({
|
||||
cfg: {
|
||||
plugins: {
|
||||
entries: {
|
||||
openrouter: {
|
||||
enabled: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
model: {
|
||||
const baseStreamFn: StreamFn = (model, _context, options) => {
|
||||
options?.onPayload?.(payload, model);
|
||||
return {} as ReturnType<StreamFn>;
|
||||
};
|
||||
const streamFn = createOpenRouterSystemCacheWrapper(baseStreamFn);
|
||||
void streamFn(
|
||||
{
|
||||
api: "openai-completions",
|
||||
provider: "openrouter",
|
||||
id: modelId,
|
||||
} as Model<"openai-completions">,
|
||||
mockProviderRuntime: true,
|
||||
payload,
|
||||
});
|
||||
} as never,
|
||||
{ messages: [] } as never,
|
||||
{},
|
||||
);
|
||||
}
|
||||
|
||||
describe("extra-params: OpenRouter Anthropic cache_control", () => {
|
||||
|
||||
@@ -7,7 +7,7 @@ import { normalizeOptionalLowercaseString, readStringValue } from "../../shared/
|
||||
import {
|
||||
patchCodexNativeWebSearchPayload,
|
||||
resolveCodexNativeSearchActivation,
|
||||
} from "../codex-native-web-search.js";
|
||||
} from "../codex-native-web-search-core.js";
|
||||
import { flattenCompletionMessagesToStringContent } from "../openai-completions-string-content.js";
|
||||
import { resolveOpenAIReasoningEffortForModel } from "../openai-reasoning-effort.js";
|
||||
import {
|
||||
|
||||
Reference in New Issue
Block a user