Files
openclaw/src/plugins/compaction-provider.ts
DhruvBhatia0 12331f0463 feat: add pluggable compaction provider registry (#56224)
Merged via squash.

Prepared head SHA: 0cc9cf3f30
Co-authored-by: DhruvBhatia0 <69252327+DhruvBhatia0@users.noreply.github.com>
Co-authored-by: jalehman <550978+jalehman@users.noreply.github.com>
Reviewed-by: @jalehman
2026-04-07 10:55:34 -07:00

133 lines
4.8 KiB
TypeScript

/**
* 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<string>;
}
// ---------------------------------------------------------------------------
// 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<string, RegisteredCompactionProvider>;
};
// 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<string, RegisteredCompactionProvider>(),
};
}
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);
}
}