/** * Compaction provider registry — process-global singleton. * * Plugins implement the CompactionProvider interface and register via * `registerCompactionProvider()`. The compaction safeguard checks this * registry before falling back to the built-in `summarizeInStages()`. */ // --------------------------------------------------------------------------- // Provider interface // --------------------------------------------------------------------------- /** * A pluggable compaction provider that can replace the built-in * summarizeInStages pipeline. */ export type CompactionProviderSummarizationInstructions = { identifierPolicy?: "strict" | "off" | "custom"; identifierInstructions?: string; }; export interface CompactionProvider { id: string; label: string; summarize(params: { messages: unknown[]; signal?: AbortSignal; compressionRatio?: number; customInstructions?: string; summarizationInstructions?: CompactionProviderSummarizationInstructions; /** Summary from a prior compaction round, if re-compacting. */ previousSummary?: string; }): Promise; } // --------------------------------------------------------------------------- // Registered entry (mirrors RegisteredMemoryEmbeddingProvider pattern) // --------------------------------------------------------------------------- /** A compaction provider with its owning plugin id for lifecycle tracking. */ export type RegisteredCompactionProvider = { provider: CompactionProvider; ownerPluginId?: string; }; // --------------------------------------------------------------------------- // Registry (process-global singleton) // --------------------------------------------------------------------------- const COMPACTION_PROVIDER_REGISTRY_STATE = Symbol.for("openclaw.compactionProviderRegistryState"); type CompactionProviderRegistryState = { providers: Map; }; // Keep compaction-provider registrations process-global so duplicated dist // chunks still share one registry map at runtime. function getCompactionProviderRegistryState(): CompactionProviderRegistryState { const globalState = globalThis as typeof globalThis & { [COMPACTION_PROVIDER_REGISTRY_STATE]?: CompactionProviderRegistryState; }; if (!globalState[COMPACTION_PROVIDER_REGISTRY_STATE]) { globalState[COMPACTION_PROVIDER_REGISTRY_STATE] = { providers: new Map(), }; } return globalState[COMPACTION_PROVIDER_REGISTRY_STATE]; } // --------------------------------------------------------------------------- // Registration // --------------------------------------------------------------------------- /** * Register a compaction provider implementation. * Pass `ownerPluginId` so the loader can snapshot/restore correctly. */ export function registerCompactionProvider( provider: CompactionProvider, options?: { ownerPluginId?: string }, ): void { getCompactionProviderRegistryState().providers.set(provider.id, { provider, ownerPluginId: options?.ownerPluginId, }); } // --------------------------------------------------------------------------- // Lookup // --------------------------------------------------------------------------- /** Return the provider for the given id, or undefined. */ export function getCompactionProvider(id: string): CompactionProvider | undefined { return getCompactionProviderRegistryState().providers.get(id)?.provider; } /** Return the registered entry (provider + owner) for the given id. */ export function getRegisteredCompactionProvider( id: string, ): RegisteredCompactionProvider | undefined { return getCompactionProviderRegistryState().providers.get(id); } /** List all registered compaction provider ids. */ export function listCompactionProviderIds(): string[] { return [...getCompactionProviderRegistryState().providers.keys()]; } /** List all registered entries with owner metadata (for snapshot/restore). */ export function listRegisteredCompactionProviders(): RegisteredCompactionProvider[] { return Array.from(getCompactionProviderRegistryState().providers.values()); } // --------------------------------------------------------------------------- // Lifecycle (clear / restore) — mirrors memory-embedding-providers.ts // --------------------------------------------------------------------------- /** Clear all compaction providers. Used by clearPluginLoaderCache() and reload. */ export function clearCompactionProviders(): void { getCompactionProviderRegistryState().providers.clear(); } /** Restore from a snapshot, replacing all current entries. */ export function restoreRegisteredCompactionProviders( entries: RegisteredCompactionProvider[], ): void { const map = getCompactionProviderRegistryState().providers; map.clear(); for (const entry of entries) { map.set(entry.provider.id, entry); } }