Files
openclaw/src/agents/tools/web-tool-runtime-context.ts
T
Peter Steinberger db73b59c04 refactor: burn wrapper shadowing baseline entries (#122040)
* refactor: burn wrapper shadowing entries

* chore: refresh wrapper shadowing baselines

* test: update secrets runtime state mocks

* fix(ci): absorb Control UI build identity variance
2026-08-11 08:24:03 -07:00

127 lines
4.4 KiB
TypeScript

/**
* Late-bound runtime context for web fetch/search tools.
*
* Resolves active secrets/runtime provider metadata for long-lived tool instances.
*/
import type { OpenClawConfig } from "../../config/types.openclaw.js";
import { resolveManifestContractOwnerPluginId } from "../../plugins/plugin-registry.js";
import { getActiveSecretsRuntimeConfigSnapshot } from "../../secrets/runtime-state.js";
import { getActiveRuntimeWebToolsMetadataFromState } from "../../secrets/runtime-web-tools-state.js";
import type {
RuntimeWebFetchMetadata,
RuntimeWebSearchMetadata,
} from "../../secrets/runtime-web-tools.types.js";
type WebProviderKind = "fetch" | "search";
type WebProviderRuntimeMetadata = RuntimeWebFetchMetadata | RuntimeWebSearchMetadata;
type ResolvedWebToolRuntimeContext<TMetadata extends WebProviderRuntimeMetadata> = {
config?: OpenClawConfig;
preferRuntimeProviders: boolean;
providerSelectionId: string;
runtimeMetadata?: TMetadata;
};
function resolveConfiguredWebProviderId(
config: OpenClawConfig | undefined,
kind: WebProviderKind,
): string {
const provider = config?.tools?.web?.[kind]?.provider;
return typeof provider === "string" ? provider.trim().toLowerCase() : "";
}
function resolveRuntimeWebProviderId(metadata: WebProviderRuntimeMetadata | undefined): string {
return metadata?.selectedProvider ?? metadata?.providerConfigured ?? "";
}
function shouldPreferRuntimeProviders(params: {
config?: OpenClawConfig;
kind: WebProviderKind;
providerSelectionId: string;
}): boolean {
// Agent-side web_search must use the live runtime registry; runWebSearch
// applies manifest ownership only as a load-scope hint after that.
if (!params.providerSelectionId || params.kind === "search") {
return true;
}
// Built-in providers are handled by core; plugin-owned selections should route through plugins.
return !resolveManifestContractOwnerPluginId({
contract: "webFetchProviders",
value: params.providerSelectionId,
origin: "bundled",
config: params.config,
});
}
function resolveWebToolRuntimeContext<TMetadata extends WebProviderRuntimeMetadata>(params: {
capturedConfig?: OpenClawConfig;
capturedRuntimeMetadata?: TMetadata;
kind: WebProviderKind;
lateBindRuntimeConfig?: boolean;
}): ResolvedWebToolRuntimeContext<TMetadata> {
const activeWebTools =
params.lateBindRuntimeConfig === true ? getActiveRuntimeWebToolsMetadataFromState() : null;
// Late-bound metadata wins over constructor-captured metadata for long-lived tool instances.
const runtimeMetadata = (activeWebTools?.[params.kind] ?? params.capturedRuntimeMetadata) as
| TMetadata
| undefined;
const config =
params.lateBindRuntimeConfig === true
? (getActiveSecretsRuntimeConfigSnapshot()?.config ?? params.capturedConfig)
: params.capturedConfig;
const providerSelectionId =
resolveRuntimeWebProviderId(runtimeMetadata) ||
resolveConfiguredWebProviderId(config, params.kind);
return {
config,
preferRuntimeProviders: shouldPreferRuntimeProviders({
config,
kind: params.kind,
providerSelectionId,
}),
providerSelectionId,
runtimeMetadata,
};
}
/** Resolves runtime provider context for the web_search tool. */
export function resolveWebSearchToolRuntimeContext(params: {
config?: OpenClawConfig;
lateBindRuntimeConfig?: boolean;
runtimeWebSearch?: RuntimeWebSearchMetadata;
}) {
const resolved = resolveWebToolRuntimeContext({
capturedConfig: params.config,
capturedRuntimeMetadata: params.runtimeWebSearch,
kind: "search",
lateBindRuntimeConfig: params.lateBindRuntimeConfig,
});
return {
config: resolved.config,
preferRuntimeProviders: resolved.preferRuntimeProviders,
providerSelectionId: resolved.providerSelectionId,
runtimeWebSearch: resolved.runtimeMetadata,
};
}
/** Resolves runtime provider context for the web_fetch tool. */
export function resolveWebFetchToolRuntimeContext(params: {
config?: OpenClawConfig;
lateBindRuntimeConfig?: boolean;
runtimeWebFetch?: RuntimeWebFetchMetadata;
}) {
const resolved = resolveWebToolRuntimeContext({
capturedConfig: params.config,
capturedRuntimeMetadata: params.runtimeWebFetch,
kind: "fetch",
lateBindRuntimeConfig: params.lateBindRuntimeConfig,
});
return {
config: resolved.config,
preferRuntimeProviders: resolved.preferRuntimeProviders,
providerSelectionId: resolved.providerSelectionId,
runtimeWebFetch: resolved.runtimeMetadata,
};
}