import { a as normalizeLowercaseStringOrEmpty, c as normalizeOptionalString, s as normalizeOptionalLowercaseString } from "./string-coerce-mnp54Vah.js";
import { o as isRecord } from "./record-coerce-DHZ4bFlT.js";
import { d as normalizeTrimmedStringList } from "./string-normalization-WNUDCpXX.js";
import { s as resolveRuntimeServiceVersion } from "./version-Crcn9X9T.js";
import { i as normalizeProviderId } from "./provider-id-Dq06Bcx6.js";
import { t as asBoolean } from "./boolean-By0bZpFH.js";
import { t as listOpenClawPluginManifestMetadata } from "./manifest-metadata-scan-CmWfUx0O.js";
//#region src/agents/provider-attribution.ts
/**
* Provider endpoint attribution and request capability resolver.
*
* Classifies provider routes so transports know which attribution headers, payload features, and endpoint policies apply.
*/
function readCompatBoolean(compat, key) {
	if (!compat || typeof compat !== "object") return;
	return asBoolean(compat[key]);
}
const OPENCLAW_ATTRIBUTION_PRODUCT = "OpenClaw";
const OPENCLAW_ATTRIBUTION_ORIGINATOR = "openclaw";
const OPENROUTER_ATTRIBUTION_CATEGORIES = "cli-agent,cloud-agent,programming-app,creative-writing,writing-assistant,general-chat,personal-agent";
const LOCAL_ENDPOINT_HOSTS = new Set([
	"localhost",
	"127.0.0.1",
	"::1",
	"[::1]"
]);
const OPENAI_RESPONSES_APIS = new Set([
	"openai-responses",
	"azure-openai-responses",
	"openai-chatgpt-responses"
]);
const OPENAI_RESPONSES_PROVIDERS = new Set([
	"openai",
	"azure-openai",
	"azure-openai-responses"
]);
const MANIFEST_PROVIDER_ENDPOINT_CLASSES = new Set([
	"anthropic-public",
	"cerebras-native",
	"chutes-native",
	"deepseek-native",
	"github-copilot-native",
	"groq-native",
	"mistral-public",
	"moonshot-native",
	"modelstudio-native",
	"nvidia-native",
	"openai-public",
	"openai",
	"opencode-native",
	"azure-openai",
	"openrouter",
	"xai-native",
	"xiaomi-native",
	"zai-native",
	"google-generative-ai",
	"google-vertex"
]);
let manifestProviderEndpointCache = null;
let manifestProviderRequestCache = null;
function formatOpenClawUserAgent(version) {
	return `${OPENCLAW_ATTRIBUTION_ORIGINATOR}/${version}`;
}
function tryParseHostname(value) {
	try {
		return normalizeOptionalLowercaseString(new URL(value).hostname);
	} catch {
		return;
	}
}
function isSchemelessHostnameCandidate(value) {
	return /^[a-z0-9.[\]-]+(?::\d+)?(?:[/?#].*)?$/i.test(value);
}
function resolveUrlHostname(value) {
	const trimmed = normalizeOptionalString(value);
	if (!trimmed) return;
	const parsedHostname = tryParseHostname(trimmed);
	if (parsedHostname) return parsedHostname;
	if (!isSchemelessHostnameCandidate(trimmed)) return;
	return tryParseHostname(`https://${trimmed}`);
}
function normalizeComparableBaseUrl(value) {
	const trimmed = normalizeOptionalString(value);
	if (!trimmed) return;
	const parsedValue = tryParseHostname(trimmed) || !isSchemelessHostnameCandidate(trimmed) ? trimmed : `https://${trimmed}`;
	try {
		const url = new URL(parsedValue);
		if (url.protocol !== "http:" && url.protocol !== "https:") return;
		url.hash = "";
		url.search = "";
		return normalizeOptionalLowercaseString(url.toString().replace(/\/+$/, ""));
	} catch {
		return;
	}
}
function isManifestProviderEndpointClass(value) {
	return MANIFEST_PROVIDER_ENDPOINT_CLASSES.has(value);
}
function readManifestProviderEndpoints(manifest) {
	if (!Array.isArray(manifest.providerEndpoints)) return [];
	const entries = [];
	for (const rawEndpoint of manifest.providerEndpoints) {
		if (!isRecord(rawEndpoint)) continue;
		const endpointClassRaw = normalizeOptionalString(rawEndpoint.endpointClass);
		if (!endpointClassRaw || !isManifestProviderEndpointClass(endpointClassRaw)) continue;
		entries.push({
			endpointClass: endpointClassRaw,
			hosts: normalizeTrimmedStringList(rawEndpoint.hosts).map((host) => host.toLowerCase()),
			hostSuffixes: normalizeTrimmedStringList(rawEndpoint.hostSuffixes).map((host) => host.toLowerCase()),
			normalizedBaseUrls: normalizeTrimmedStringList(rawEndpoint.baseUrls).map((baseUrl) => normalizeComparableBaseUrl(baseUrl)).filter((baseUrl) => baseUrl !== void 0),
			...normalizeOptionalString(rawEndpoint.googleVertexRegion) ? { googleVertexRegion: normalizeOptionalString(rawEndpoint.googleVertexRegion) } : {},
			...normalizeOptionalString(rawEndpoint.googleVertexRegionHostSuffix) ? { googleVertexRegionHostSuffix: normalizeOptionalString(rawEndpoint.googleVertexRegionHostSuffix) } : {}
		});
	}
	return entries;
}
function readManifestProviderRequests(manifest) {
	const providerRequest = manifest.providerRequest;
	if (!isRecord(providerRequest) || !isRecord(providerRequest.providers)) return [];
	const entries = [];
	for (const [providerRaw, requestRaw] of Object.entries(providerRequest.providers)) {
		if (!isRecord(requestRaw)) continue;
		const provider = normalizeLowercaseStringOrEmpty(providerRaw);
		if (!provider) continue;
		const compatibilityFamily = normalizeOptionalString(requestRaw.compatibilityFamily) === "moonshot" ? "moonshot" : void 0;
		const supportsStreamingUsage = isRecord(requestRaw.openAICompletions) ? requestRaw.openAICompletions.supportsStreamingUsage : void 0;
		entries.push([provider, {
			...normalizeOptionalString(requestRaw.family) ? { family: normalizeOptionalString(requestRaw.family) } : {},
			...compatibilityFamily ? { compatibilityFamily } : {},
			...typeof supportsStreamingUsage === "boolean" ? { supportsOpenAICompletionsStreamingUsageCompat: supportsStreamingUsage } : {}
		}]);
	}
	return entries;
}
function collectManifestProviderEndpoints() {
	const entries = [];
	for (const { manifest } of listOpenClawPluginManifestMetadata()) entries.push(...readManifestProviderEndpoints(manifest));
	return entries;
}
function collectManifestProviderRequests() {
	const entries = /* @__PURE__ */ new Map();
	for (const { manifest } of listOpenClawPluginManifestMetadata()) for (const [provider, request] of readManifestProviderRequests(manifest)) entries.set(provider, request);
	return entries;
}
function loadManifestProviderEndpointCache() {
	if (!manifestProviderEndpointCache) manifestProviderEndpointCache = collectManifestProviderEndpoints();
	return manifestProviderEndpointCache;
}
function loadManifestProviderRequestCache() {
	if (!manifestProviderRequestCache) manifestProviderRequestCache = collectManifestProviderRequests();
	return manifestProviderRequestCache;
}
function resolveManifestProviderRequest(provider) {
	return provider ? loadManifestProviderRequestCache().get(provider) : void 0;
}
function hostMatchesSuffix(host, suffix) {
	if (!suffix) return false;
	return suffix.startsWith(".") || suffix.startsWith("-") ? host.endsWith(suffix) : host === suffix || host.endsWith(`.${suffix}`);
}
function buildManifestEndpointResolution(endpoint, host) {
	const regionSuffix = endpoint.googleVertexRegionHostSuffix;
	const googleVertexRegion = endpoint.googleVertexRegion ?? (regionSuffix && host.endsWith(regionSuffix) ? host.slice(0, -regionSuffix.length) : void 0);
	return {
		endpointClass: endpoint.endpointClass,
		hostname: host,
		...googleVertexRegion ? { googleVertexRegion } : {}
	};
}
function resolveManifestProviderEndpoint(params) {
	for (const endpoint of loadManifestProviderEndpointCache()) {
		if (endpoint.hosts.includes(params.host)) return buildManifestEndpointResolution(endpoint, params.host);
		if (endpoint.hostSuffixes.some((suffix) => hostMatchesSuffix(params.host, suffix))) return buildManifestEndpointResolution(endpoint, params.host);
		if (params.normalizedBaseUrl && endpoint.normalizedBaseUrls.includes(params.normalizedBaseUrl)) return buildManifestEndpointResolution(endpoint, params.host);
	}
}
function isLocalEndpointHost(host) {
	return LOCAL_ENDPOINT_HOSTS.has(host) || host.endsWith(".localhost") || host.endsWith(".local") || host.endsWith(".internal");
}
function resolveProviderEndpoint(baseUrl) {
	if (typeof baseUrl !== "string" || !baseUrl.trim()) return { endpointClass: "default" };
	const host = resolveUrlHostname(baseUrl);
	if (!host) return { endpointClass: "invalid" };
	const manifestEndpoint = resolveManifestProviderEndpoint({
		host,
		normalizedBaseUrl: normalizeComparableBaseUrl(baseUrl)
	});
	if (manifestEndpoint) return manifestEndpoint;
	if (isLocalEndpointHost(host)) return {
		endpointClass: "local",
		hostname: host
	};
	return {
		endpointClass: "custom",
		hostname: host
	};
}
function resolveKnownProviderFamily(provider) {
	const manifestFamily = resolveManifestProviderRequest(provider)?.family;
	if (manifestFamily) return manifestFamily;
	switch (provider) {
		case "openai":
		case "azure-openai":
		case "azure-openai-responses": return "openai-family";
		default: return provider || "unknown";
	}
}
function isOpenAIResponsesApi(api) {
	const normalizedApi = normalizeOptionalLowercaseString(api);
	return normalizedApi !== void 0 && OPENAI_RESPONSES_APIS.has(normalizedApi);
}
function isCanonicalOrLegacyOpenAIProvider(provider) {
	return provider === "openai";
}
function resolveProviderAttributionIdentity(env = process.env) {
	return {
		product: OPENCLAW_ATTRIBUTION_PRODUCT,
		version: resolveRuntimeServiceVersion(env)
	};
}
function buildOpenRouterAttributionPolicy(env = process.env) {
	const identity = resolveProviderAttributionIdentity(env);
	return {
		provider: "openrouter",
		enabledByDefault: true,
		verification: "vendor-documented",
		hook: "request-headers",
		docsUrl: "https://openrouter.ai/docs/app-attribution",
		reviewNote: "Documented app attribution headers. Verified in OpenClaw runtime wrapper.",
		...identity,
		headers: {
			"HTTP-Referer": "https://openclaw.ai",
			"X-OpenRouter-Title": identity.product,
			"X-OpenRouter-Categories": OPENROUTER_ATTRIBUTION_CATEGORIES
		}
	};
}
function buildNvidiaAttributionPolicy(env = process.env) {
	return {
		provider: "nvidia",
		enabledByDefault: true,
		verification: "vendor-documented",
		hook: "request-headers",
		reviewNote: "NVIDIA NIM billing invoke-origin attribution header. Applied only on verified NVIDIA routes.",
		...resolveProviderAttributionIdentity(env),
		headers: { "X-BILLING-INVOKE-ORIGIN": OPENCLAW_ATTRIBUTION_PRODUCT }
	};
}
function buildOpenAIAttributionPolicy(env = process.env) {
	const identity = resolveProviderAttributionIdentity(env);
	return {
		provider: "openai",
		enabledByDefault: true,
		verification: "vendor-hidden-api-spec",
		hook: "request-headers",
		reviewNote: "OpenAI native traffic supports hidden originator/User-Agent attribution. Verified against the Codex wire contract.",
		...identity,
		headers: {
			originator: OPENCLAW_ATTRIBUTION_ORIGINATOR,
			version: identity.version,
			"User-Agent": formatOpenClawUserAgent(identity.version)
		}
	};
}
function buildXaiAttributionPolicy(env = process.env) {
	const identity = resolveProviderAttributionIdentity(env);
	return {
		provider: "xai",
		enabledByDefault: true,
		verification: "vendor-hidden-api-spec",
		hook: "request-headers",
		reviewNote: "xAI api.x.ai accepts a standard openclaw User-Agent. Companion originator/version headers mirror the OpenAI attribution shape for consistency; they are not validated against an xAI-specific spec and are expected to be ignored by xAI's OpenAI-compatible surface.",
		...identity,
		headers: {
			originator: OPENCLAW_ATTRIBUTION_ORIGINATOR,
			version: identity.version,
			"User-Agent": formatOpenClawUserAgent(identity.version)
		}
	};
}
function buildSdkHookOnlyPolicy(provider, hook, reviewNote, env = process.env) {
	return {
		provider,
		enabledByDefault: false,
		verification: "vendor-sdk-hook-only",
		hook,
		reviewNote,
		...resolveProviderAttributionIdentity(env)
	};
}
function listProviderAttributionPolicies(env = process.env) {
	return [
		buildOpenRouterAttributionPolicy(env),
		buildNvidiaAttributionPolicy(env),
		buildOpenAIAttributionPolicy(env),
		buildXaiAttributionPolicy(env),
		buildSdkHookOnlyPolicy("anthropic", "default-headers", "Anthropic JS SDK exposes defaultHeaders, but app attribution is not yet verified.", env),
		buildSdkHookOnlyPolicy("google", "user-agent-extra", "Google GenAI JS SDK exposes userAgentExtra/httpOptions, but provider-side attribution is not yet verified.", env),
		buildSdkHookOnlyPolicy("groq", "default-headers", "Groq JS SDK exposes defaultHeaders, but app attribution is not yet verified.", env),
		buildSdkHookOnlyPolicy("mistral", "custom-user-agent", "Mistral JS SDK exposes a custom userAgent option, but app attribution is not yet verified.", env),
		buildSdkHookOnlyPolicy("together", "default-headers", "Together JS SDK exposes defaultHeaders, but app attribution is not yet verified.", env)
	];
}
function resolveProviderAttributionPolicy(provider, env = process.env) {
	const normalized = normalizeProviderId(provider ?? "");
	const canonical = normalized === "openai" ? "openai" : normalized;
	return listProviderAttributionPolicies(env).find((policy) => policy.provider === canonical);
}
function resolveProviderRequestPolicy(input, env = process.env) {
	const provider = normalizeProviderId(input.provider ?? "");
	const policy = resolveProviderAttributionPolicy(provider, env);
	const endpointClass = resolveProviderEndpoint(input.baseUrl).endpointClass;
	const usesConfiguredBaseUrl = endpointClass !== "default";
	const usesKnownNativeOpenAIEndpoint = endpointClass === "openai-public" || endpointClass === "openai" || endpointClass === "azure-openai";
	const usesVerifiedOpenAIAttributionHost = endpointClass === "openai-public" || endpointClass === "openai";
	const usesXaiNativeAttributionHost = endpointClass === "xai-native";
	const usesExplicitProxyLikeEndpoint = usesConfiguredBaseUrl && !usesKnownNativeOpenAIEndpoint;
	let attributionProvider;
	if (isCanonicalOrLegacyOpenAIProvider(provider) && usesVerifiedOpenAIAttributionHost) attributionProvider = "openai";
	else if (provider === "openrouter" && policy?.enabledByDefault) {
		if (endpointClass === "openrouter" || endpointClass === "default") attributionProvider = "openrouter";
	} else if (provider === "xai" && policy?.enabledByDefault) {
		if (usesXaiNativeAttributionHost || endpointClass === "default") attributionProvider = "xai";
	}
	if (!attributionProvider && endpointClass === "nvidia-native") attributionProvider = "nvidia";
	const attributionPolicy = attributionProvider ? resolveProviderAttributionPolicy(attributionProvider, env) : void 0;
	const attributionHeaders = attributionPolicy?.enabledByDefault ? attributionPolicy.headers : void 0;
	return {
		provider: provider || void 0,
		policy: attributionPolicy ?? policy,
		endpointClass,
		usesConfiguredBaseUrl,
		knownProviderFamily: resolveKnownProviderFamily(provider || void 0),
		attributionProvider,
		attributionHeaders,
		allowsHiddenAttribution: attributionProvider !== void 0 && attributionPolicy?.verification === "vendor-hidden-api-spec",
		usesKnownNativeOpenAIEndpoint,
		usesKnownNativeOpenAIRoute: endpointClass === "default" ? isCanonicalOrLegacyOpenAIProvider(provider) : usesKnownNativeOpenAIEndpoint,
		usesVerifiedOpenAIAttributionHost,
		usesExplicitProxyLikeEndpoint
	};
}
function resolveProviderRequestCapabilities(input, env = process.env) {
	const policy = resolveProviderRequestPolicy(input, env);
	const provider = policy.provider;
	const api = normalizeOptionalLowercaseString(input.api);
	const endpointClass = policy.endpointClass;
	const isKnownNativeEndpoint = endpointClass === "anthropic-public" || endpointClass === "cerebras-native" || endpointClass === "chutes-native" || endpointClass === "deepseek-native" || endpointClass === "github-copilot-native" || endpointClass === "groq-native" || endpointClass === "mistral-public" || endpointClass === "moonshot-native" || endpointClass === "modelstudio-native" || endpointClass === "nvidia-native" || endpointClass === "openai-public" || endpointClass === "openai" || endpointClass === "opencode-native" || endpointClass === "azure-openai" || endpointClass === "openrouter" || endpointClass === "xai-native" || endpointClass === "xiaomi-native" || endpointClass === "zai-native" || endpointClass === "google-generative-ai" || endpointClass === "google-vertex";
	const manifestProviderRequest = resolveManifestProviderRequest(provider);
	const compatibilityFamily = manifestProviderRequest?.compatibilityFamily;
	const isResponsesApi = isOpenAIResponsesApi(api);
	const promptCacheKeySupport = readCompatBoolean(input.compat, "supportsPromptCacheKey");
	const shouldStripResponsesPromptCache = promptCacheKeySupport === true ? false : promptCacheKeySupport === false ? isResponsesApi : isResponsesApi && policy.usesExplicitProxyLikeEndpoint;
	return {
		...policy,
		isKnownNativeEndpoint,
		allowsOpenAIServiceTier: isCanonicalOrLegacyOpenAIProvider(provider) && api === "openai-responses" && endpointClass === "openai-public" || isCanonicalOrLegacyOpenAIProvider(provider) && (api === "openai-chatgpt-responses" || api === "openai-responses") && endpointClass === "openai",
		supportsOpenAIReasoningCompatPayload: provider !== void 0 && api !== void 0 && !policy.usesExplicitProxyLikeEndpoint && (isCanonicalOrLegacyOpenAIProvider(provider) || provider === "azure-openai" || provider === "azure-openai-responses") && (api === "openai-completions" || api === "openai-responses" || api === "openai-chatgpt-responses" || api === "azure-openai-responses"),
		allowsAnthropicServiceTier: provider === "anthropic" && api === "anthropic-messages" && (endpointClass === "default" || endpointClass === "anthropic-public"),
		supportsResponsesStoreField: readCompatBoolean(input.compat, "supportsStore") !== false && isResponsesApi,
		allowsResponsesStore: readCompatBoolean(input.compat, "supportsStore") !== false && provider !== void 0 && isResponsesApi && OPENAI_RESPONSES_PROVIDERS.has(provider) && policy.usesKnownNativeOpenAIEndpoint,
		shouldStripResponsesPromptCache,
		supportsNativeStreamingUsageCompat: endpointClass === "moonshot-native" || endpointClass === "modelstudio-native",
		supportsOpenAICompletionsStreamingUsageCompat: manifestProviderRequest?.supportsOpenAICompletionsStreamingUsageCompat === true,
		compatibilityFamily
	};
}
function describeProviderRequestRoutingPolicy(policy) {
	if (!policy.attributionProvider) return "none";
	switch (policy.policy?.verification) {
		case "vendor-hidden-api-spec": return "hidden";
		case "vendor-documented": return "documented";
		case "vendor-sdk-hook-only": return "sdk-hook-only";
		default: return "none";
	}
}
function describeProviderRequestRouteClass(policy) {
	if (policy.endpointClass === "default") return "default";
	if (policy.endpointClass === "invalid") return "invalid";
	if (policy.endpointClass === "local") return "local";
	if (policy.endpointClass === "custom" || policy.endpointClass === "openrouter") return "proxy-like";
	return "native";
}
function describeProviderRequestRoutingSummary(input, env = process.env) {
	const policy = resolveProviderRequestPolicy(input, env);
	const api = normalizeOptionalLowercaseString(input.api) ?? "unknown";
	const provider = policy.provider ?? "unknown";
	const routeClass = describeProviderRequestRouteClass(policy);
	const routingPolicy = describeProviderRequestRoutingPolicy(policy);
	return [
		`provider=${provider}`,
		`api=${api}`,
		`endpoint=${policy.endpointClass}`,
		`route=${routeClass}`,
		`policy=${routingPolicy}`
	].join(" ");
}
//#endregion
export { resolveProviderRequestPolicy as i, resolveProviderEndpoint as n, resolveProviderRequestCapabilities as r, describeProviderRequestRoutingSummary as t };
