import { A as resolvePositiveTimerTimeoutMs, n as MAX_TIMER_TIMEOUT_MS } from "./number-coercion-CJQ8TR--.js";
import { _ as uniqueStrings, l as normalizeStringEntries } from "./string-normalization-CRyoFBPt.js";
import { i as clampNumber, r as clampInt } from "./utils-d4Gq0rDX.js";
import { n as findNormalizedProviderValue, r as normalizeProviderId } from "./provider-id-BIcU_2-A.js";
import "./agent-scope-uF6sww3K.js";
import { r as resolveAgentConfig } from "./agent-scope-config-BGhyaQxC.js";
import { v as resolveOpenClawAgentSqlitePath } from "./openclaw-agent-db-C4OFXhEu.js";
import { C as getMemoryEmbeddingProvider } from "./registry-4I32cXab.js";
import { n as assertSecretOwnerAvailable } from "./runtime-degraded-state-DhM9_UYj.js";
import { t as runtimeMemorySecretOwnerId } from "./runtime-memory-secret-owner-CRIh0blb.js";
import { a as isMemoryMultimodalEnabled, o as normalizeMemoryMultimodalSettings } from "./multimodal-1dt2YOuy.js";
import { t as getEmbeddingProvider } from "./embedding-provider-runtime-DBl9fk9w.js";
//#region src/agents/memory-search.ts
/**
* Resolves memory-search source, sync, and ranking configuration.
*/
const DEFAULT_CHUNK_TOKENS = 400;
const DEFAULT_CHUNK_OVERLAP = 80;
const DEFAULT_WATCH_DEBOUNCE_MS = 1500;
const DEFAULT_SESSION_DELTA_BYTES = 1e5;
const DEFAULT_SESSION_DELTA_MESSAGES = 50;
const DEFAULT_MAX_RESULTS = 6;
const DEFAULT_MIN_SCORE = .35;
const DEFAULT_HYBRID_ENABLED = true;
const DEFAULT_HYBRID_VECTOR_WEIGHT = .7;
const DEFAULT_HYBRID_TEXT_WEIGHT = .3;
const DEFAULT_HYBRID_CANDIDATE_MULTIPLIER = 4;
const DEFAULT_MMR_ENABLED = false;
const DEFAULT_MMR_LAMBDA = .7;
const DEFAULT_TEMPORAL_DECAY_ENABLED = false;
const DEFAULT_TEMPORAL_DECAY_HALF_LIFE_DAYS = 30;
const DEFAULT_CACHE_ENABLED = true;
const DEFAULT_SOURCES = ["memory"];
const DEFAULT_MEMORY_EMBEDDING_PROVIDER = "openai";
const DEFAULT_REMOTE_BATCH_POLL_INTERVAL_MS = 2e3;
const DEFAULT_REMOTE_BATCH_TIMEOUT_MINUTES = 60;
const MAX_REMOTE_BATCH_TIMEOUT_MINUTES = Math.floor(MAX_TIMER_TIMEOUT_MS / 6e4);
function resolveRemoteBatchPollIntervalMs(overrideValue, defaultValue) {
	return resolvePositiveTimerTimeoutMs(overrideValue ?? defaultValue, DEFAULT_REMOTE_BATCH_POLL_INTERVAL_MS);
}
function resolveRemoteBatchTimeoutMinutes(overrideValue, defaultValue) {
	const value = overrideValue ?? defaultValue;
	return typeof value === "number" && Number.isFinite(value) && value > 0 ? clampInt(value, 1, MAX_REMOTE_BATCH_TIMEOUT_MINUTES) : DEFAULT_REMOTE_BATCH_TIMEOUT_MINUTES;
}
function normalizeSources(sources, sessionMemoryEnabled) {
	const normalized = /* @__PURE__ */ new Set();
	const input = sources?.length ? sources : DEFAULT_SOURCES;
	for (const source of input) {
		if (source === "memory") normalized.add("memory");
		if (source === "sessions" && sessionMemoryEnabled) normalized.add("sessions");
	}
	if (normalized.size === 0) normalized.add("memory");
	return Array.from(normalized);
}
function getConfiguredMemoryEmbeddingProvider(providerId, cfg) {
	if (normalizeProviderId(providerId) === "none") return;
	const directAdapter = getMemoryEmbeddingProvider(providerId);
	if (directAdapter) return directAdapter;
	const genericAdapter = getEmbeddingProvider(providerId, cfg);
	if (genericAdapter) return genericAdapter;
	const ownerApi = findNormalizedProviderValue(cfg.models?.providers, providerId)?.api?.trim();
	if (!ownerApi) return;
	const normalizedProvider = normalizeProviderId(providerId);
	const normalizedOwner = normalizeProviderId(ownerApi);
	if (!normalizedOwner || normalizedOwner === normalizedProvider) return;
	return getMemoryEmbeddingProvider(normalizedOwner);
}
function mergeConfig(cfg, defaults, overrides, agentId) {
	const enabled = overrides?.enabled ?? defaults?.enabled ?? true;
	const rememberAcrossConversations = overrides?.rememberAcrossConversations ?? defaults?.rememberAcrossConversations ?? false;
	const configuredSessionMemory = overrides?.experimental?.sessionMemory ?? defaults?.experimental?.sessionMemory ?? false;
	const sessionMemory = rememberAcrossConversations || configuredSessionMemory;
	const rawProvider = overrides?.provider ?? defaults?.provider;
	const provider = rawProvider?.trim() === "auto" ? DEFAULT_MEMORY_EMBEDDING_PROVIDER : rawProvider?.trim() || DEFAULT_MEMORY_EMBEDDING_PROVIDER;
	const primaryAdapter = getConfiguredMemoryEmbeddingProvider(provider, cfg);
	const defaultRemote = defaults?.remote;
	const overrideRemote = overrides?.remote;
	const fallback = overrides?.fallback ?? defaults?.fallback ?? "none";
	const fallbackAdapter = normalizeProviderId(provider) !== "none" && fallback && fallback !== "none" ? getConfiguredMemoryEmbeddingProvider(fallback, cfg) : void 0;
	const includeRemote = Boolean(overrideRemote?.baseUrl || overrideRemote?.apiKey || overrideRemote?.headers || overrideRemote?.nonBatchConcurrency != null || defaultRemote?.baseUrl || defaultRemote?.apiKey || defaultRemote?.headers || defaultRemote?.nonBatchConcurrency != null) || primaryAdapter?.transport !== "local" || fallbackAdapter?.transport === "remote";
	const batch = {
		enabled: overrideRemote?.batch?.enabled ?? defaultRemote?.batch?.enabled ?? false,
		wait: overrideRemote?.batch?.wait ?? defaultRemote?.batch?.wait ?? true,
		concurrency: Math.max(1, overrideRemote?.batch?.concurrency ?? defaultRemote?.batch?.concurrency ?? 2),
		pollIntervalMs: resolveRemoteBatchPollIntervalMs(overrideRemote?.batch?.pollIntervalMs, defaultRemote?.batch?.pollIntervalMs),
		timeoutMinutes: resolveRemoteBatchTimeoutMinutes(overrideRemote?.batch?.timeoutMinutes, defaultRemote?.batch?.timeoutMinutes)
	};
	const remote = includeRemote ? {
		baseUrl: overrideRemote?.baseUrl ?? defaultRemote?.baseUrl,
		apiKey: overrideRemote?.apiKey ?? defaultRemote?.apiKey,
		headers: overrideRemote?.headers ?? defaultRemote?.headers,
		nonBatchConcurrency: overrideRemote?.nonBatchConcurrency ?? defaultRemote?.nonBatchConcurrency,
		batch
	} : void 0;
	const modelDefault = primaryAdapter?.defaultModel;
	const model = overrides?.model ?? defaults?.model ?? modelDefault ?? "";
	const inputType = overrides?.inputType?.trim() || defaults?.inputType?.trim() || void 0;
	const queryInputType = overrides?.queryInputType?.trim() || defaults?.queryInputType?.trim() || void 0;
	const documentInputType = overrides?.documentInputType?.trim() || defaults?.documentInputType?.trim() || void 0;
	const outputDimensionality = overrides?.outputDimensionality ?? defaults?.outputDimensionality;
	const local = {
		modelPath: overrides?.local?.modelPath ?? defaults?.local?.modelPath,
		modelCacheDir: overrides?.local?.modelCacheDir ?? defaults?.local?.modelCacheDir,
		contextSize: overrides?.local?.contextSize ?? defaults?.local?.contextSize
	};
	const configuredSources = overrides?.sources ?? defaults?.sources;
	const searchSources = normalizeSources(configuredSources, configuredSessionMemory || rememberAcrossConversations && configuredSources?.includes("sessions") === true);
	const sources = normalizeSources(rememberAcrossConversations ? [...searchSources, "sessions"] : configuredSources, sessionMemory);
	const extraPaths = uniqueStrings(normalizeStringEntries([...defaults?.extraPaths ?? [], ...overrides?.extraPaths ?? []]));
	const multimodal = normalizeMemoryMultimodalSettings({
		enabled: overrides?.multimodal?.enabled ?? defaults?.multimodal?.enabled,
		modalities: overrides?.multimodal?.modalities ?? defaults?.multimodal?.modalities,
		maxFileBytes: overrides?.multimodal?.maxFileBytes ?? defaults?.multimodal?.maxFileBytes
	});
	const vector = {
		enabled: overrides?.store?.vector?.enabled ?? defaults?.store?.vector?.enabled ?? true,
		extensionPath: overrides?.store?.vector?.extensionPath ?? defaults?.store?.vector?.extensionPath
	};
	const fts = { tokenizer: overrides?.store?.fts?.tokenizer ?? defaults?.store?.fts?.tokenizer ?? "unicode61" };
	const store = {
		driver: overrides?.store?.driver ?? defaults?.store?.driver ?? "sqlite",
		databasePath: resolveOpenClawAgentSqlitePath({
			agentId,
			env: process.env
		}),
		fts,
		vector
	};
	const chunking = {
		tokens: overrides?.chunking?.tokens ?? defaults?.chunking?.tokens ?? DEFAULT_CHUNK_TOKENS,
		overlap: overrides?.chunking?.overlap ?? defaults?.chunking?.overlap ?? DEFAULT_CHUNK_OVERLAP
	};
	const sync = resolveSyncConfig(defaults, overrides);
	const query = {
		maxResults: overrides?.query?.maxResults ?? defaults?.query?.maxResults ?? DEFAULT_MAX_RESULTS,
		minScore: overrides?.query?.minScore ?? defaults?.query?.minScore ?? DEFAULT_MIN_SCORE
	};
	const hybrid = {
		enabled: overrides?.query?.hybrid?.enabled ?? defaults?.query?.hybrid?.enabled ?? DEFAULT_HYBRID_ENABLED,
		vectorWeight: overrides?.query?.hybrid?.vectorWeight ?? defaults?.query?.hybrid?.vectorWeight ?? DEFAULT_HYBRID_VECTOR_WEIGHT,
		textWeight: overrides?.query?.hybrid?.textWeight ?? defaults?.query?.hybrid?.textWeight ?? DEFAULT_HYBRID_TEXT_WEIGHT,
		candidateMultiplier: overrides?.query?.hybrid?.candidateMultiplier ?? defaults?.query?.hybrid?.candidateMultiplier ?? DEFAULT_HYBRID_CANDIDATE_MULTIPLIER,
		mmr: {
			enabled: overrides?.query?.hybrid?.mmr?.enabled ?? defaults?.query?.hybrid?.mmr?.enabled ?? DEFAULT_MMR_ENABLED,
			lambda: overrides?.query?.hybrid?.mmr?.lambda ?? defaults?.query?.hybrid?.mmr?.lambda ?? DEFAULT_MMR_LAMBDA
		},
		temporalDecay: {
			enabled: overrides?.query?.hybrid?.temporalDecay?.enabled ?? defaults?.query?.hybrid?.temporalDecay?.enabled ?? DEFAULT_TEMPORAL_DECAY_ENABLED,
			halfLifeDays: overrides?.query?.hybrid?.temporalDecay?.halfLifeDays ?? defaults?.query?.hybrid?.temporalDecay?.halfLifeDays ?? DEFAULT_TEMPORAL_DECAY_HALF_LIFE_DAYS
		}
	};
	const cache = {
		enabled: overrides?.cache?.enabled ?? defaults?.cache?.enabled ?? DEFAULT_CACHE_ENABLED,
		maxEntries: overrides?.cache?.maxEntries ?? defaults?.cache?.maxEntries
	};
	const overlap = clampNumber(chunking.overlap, 0, Math.max(0, chunking.tokens - 1));
	const minScore = clampNumber(query.minScore, 0, 1);
	const vectorWeight = clampNumber(hybrid.vectorWeight, 0, 1);
	const textWeight = clampNumber(hybrid.textWeight, 0, 1);
	const sum = vectorWeight + textWeight;
	const normalizedVectorWeight = sum > 0 ? vectorWeight / sum : DEFAULT_HYBRID_VECTOR_WEIGHT;
	const normalizedTextWeight = sum > 0 ? textWeight / sum : DEFAULT_HYBRID_TEXT_WEIGHT;
	const candidateMultiplier = clampInt(hybrid.candidateMultiplier, 1, 20);
	const temporalDecayHalfLifeDays = Math.max(1, Math.floor(Number.isFinite(hybrid.temporalDecay.halfLifeDays) ? hybrid.temporalDecay.halfLifeDays : DEFAULT_TEMPORAL_DECAY_HALF_LIFE_DAYS));
	const deltaBytes = clampInt(sync.sessions.deltaBytes, 0, Number.MAX_SAFE_INTEGER);
	const deltaMessages = clampInt(sync.sessions.deltaMessages, 0, Number.MAX_SAFE_INTEGER);
	const postCompactionForce = sync.sessions.postCompactionForce;
	return {
		enabled,
		rememberAcrossConversations,
		sources,
		searchSources,
		extraPaths,
		multimodal,
		provider,
		remote,
		experimental: { sessionMemory },
		fallback,
		model,
		inputType,
		queryInputType,
		documentInputType,
		outputDimensionality,
		local,
		store,
		chunking: {
			tokens: Math.max(1, chunking.tokens),
			overlap
		},
		sync: {
			...sync,
			sessions: {
				deltaBytes,
				deltaMessages,
				postCompactionForce
			}
		},
		query: {
			...query,
			minScore,
			hybrid: {
				enabled: hybrid.enabled,
				vectorWeight: normalizedVectorWeight,
				textWeight: normalizedTextWeight,
				candidateMultiplier,
				mmr: {
					enabled: hybrid.mmr.enabled,
					lambda: Number.isFinite(hybrid.mmr.lambda) ? Math.max(0, Math.min(1, hybrid.mmr.lambda)) : DEFAULT_MMR_LAMBDA
				},
				temporalDecay: {
					enabled: hybrid.temporalDecay.enabled,
					halfLifeDays: temporalDecayHalfLifeDays
				}
			}
		},
		cache: {
			enabled: cache.enabled,
			maxEntries: typeof cache.maxEntries === "number" && Number.isFinite(cache.maxEntries) ? Math.max(1, Math.floor(cache.maxEntries)) : void 0
		}
	};
}
function resolveSyncConfig(defaults, overrides) {
	return {
		onSessionStart: overrides?.sync?.onSessionStart ?? defaults?.sync?.onSessionStart ?? true,
		onSearch: overrides?.sync?.onSearch ?? defaults?.sync?.onSearch ?? true,
		watch: overrides?.sync?.watch ?? defaults?.sync?.watch ?? true,
		watchDebounceMs: overrides?.sync?.watchDebounceMs ?? defaults?.sync?.watchDebounceMs ?? DEFAULT_WATCH_DEBOUNCE_MS,
		intervalMinutes: overrides?.sync?.intervalMinutes ?? defaults?.sync?.intervalMinutes ?? 0,
		embeddingBatchTimeoutSeconds: overrides?.sync?.embeddingBatchTimeoutSeconds ?? defaults?.sync?.embeddingBatchTimeoutSeconds,
		sessions: {
			deltaBytes: overrides?.sync?.sessions?.deltaBytes ?? defaults?.sync?.sessions?.deltaBytes ?? DEFAULT_SESSION_DELTA_BYTES,
			deltaMessages: overrides?.sync?.sessions?.deltaMessages ?? defaults?.sync?.sessions?.deltaMessages ?? DEFAULT_SESSION_DELTA_MESSAGES,
			postCompactionForce: overrides?.sync?.sessions?.postCompactionForce ?? defaults?.sync?.sessions?.postCompactionForce ?? true
		}
	};
}
function resolveMemorySearchConfig(cfg, agentId) {
	const defaults = cfg.agents?.defaults?.memorySearch;
	const overrides = resolveAgentConfig(cfg, agentId)?.memorySearch;
	const resolved = mergeConfig(cfg, defaults, overrides, agentId);
	if (!resolved.enabled) return null;
	assertSecretOwnerAvailable("capability", runtimeMemorySecretOwnerId(agentId));
	const isFtsOnly = normalizeProviderId(resolved.provider) === "none";
	const multimodalActive = isMemoryMultimodalEnabled(resolved.multimodal);
	const multimodalProvider = isFtsOnly ? void 0 : getConfiguredMemoryEmbeddingProvider(resolved.provider, cfg);
	if (!isFtsOnly && multimodalActive && (multimodalProvider && !(multimodalProvider.supportsMultimodalEmbeddings?.({ model: resolved.model }) ?? false) || !multimodalProvider && getEmbeddingProvider(resolved.provider, cfg))) throw new Error("agents.*.memorySearch.multimodal requires a provider adapter that supports multimodal embeddings for the configured model.");
	if (multimodalActive && resolved.fallback !== "none") throw new Error("agents.*.memorySearch.multimodal does not support memorySearch.fallback. Set fallback to \"none\".");
	return resolved;
}
function resolveMemorySearchSyncConfig(cfg, agentId) {
	const defaults = cfg.agents?.defaults?.memorySearch;
	const overrides = resolveAgentConfig(cfg, agentId)?.memorySearch;
	if (!(overrides?.enabled ?? defaults?.enabled ?? true)) return null;
	return resolveSyncConfig(defaults, overrides);
}
//#endregion
export { resolveMemorySearchSyncConfig as n, resolveMemorySearchConfig as t };
