mirror of https://github.com/openclaw/openclaw.git
86 lines
2.9 KiB
TypeScript
86 lines
2.9 KiB
TypeScript
import type { OpenClawConfig } from "../config/config.js";
|
|
import { defaultSlotIdForKey } from "../plugins/slots.js";
|
|
import type { ContextEngine } from "./types.js";
|
|
|
|
/**
|
|
* A factory that creates a ContextEngine instance.
|
|
* Supports async creation for engines that need DB connections etc.
|
|
*/
|
|
export type ContextEngineFactory = () => ContextEngine | Promise<ContextEngine>;
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Registry (module-level singleton)
|
|
// ---------------------------------------------------------------------------
|
|
|
|
const CONTEXT_ENGINE_REGISTRY_STATE = Symbol.for("openclaw.contextEngineRegistryState");
|
|
|
|
type ContextEngineRegistryState = {
|
|
engines: Map<string, ContextEngineFactory>;
|
|
};
|
|
|
|
// Keep context-engine registrations process-global so duplicated dist chunks
|
|
// still share one registry map at runtime.
|
|
function getContextEngineRegistryState(): ContextEngineRegistryState {
|
|
const globalState = globalThis as typeof globalThis & {
|
|
[CONTEXT_ENGINE_REGISTRY_STATE]?: ContextEngineRegistryState;
|
|
};
|
|
if (!globalState[CONTEXT_ENGINE_REGISTRY_STATE]) {
|
|
globalState[CONTEXT_ENGINE_REGISTRY_STATE] = {
|
|
engines: new Map<string, ContextEngineFactory>(),
|
|
};
|
|
}
|
|
return globalState[CONTEXT_ENGINE_REGISTRY_STATE];
|
|
}
|
|
|
|
/**
|
|
* Register a context engine implementation under the given id.
|
|
*/
|
|
export function registerContextEngine(id: string, factory: ContextEngineFactory): void {
|
|
getContextEngineRegistryState().engines.set(id, factory);
|
|
}
|
|
|
|
/**
|
|
* Return the factory for a registered engine, or undefined.
|
|
*/
|
|
export function getContextEngineFactory(id: string): ContextEngineFactory | undefined {
|
|
return getContextEngineRegistryState().engines.get(id);
|
|
}
|
|
|
|
/**
|
|
* List all registered engine ids.
|
|
*/
|
|
export function listContextEngineIds(): string[] {
|
|
return [...getContextEngineRegistryState().engines.keys()];
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Resolution
|
|
// ---------------------------------------------------------------------------
|
|
|
|
/**
|
|
* Resolve which ContextEngine to use based on plugin slot configuration.
|
|
*
|
|
* Resolution order:
|
|
* 1. `config.plugins.slots.contextEngine` (explicit slot override)
|
|
* 2. Default slot value ("legacy")
|
|
*
|
|
* Throws if the resolved engine id has no registered factory.
|
|
*/
|
|
export async function resolveContextEngine(config?: OpenClawConfig): Promise<ContextEngine> {
|
|
const slotValue = config?.plugins?.slots?.contextEngine;
|
|
const engineId =
|
|
typeof slotValue === "string" && slotValue.trim()
|
|
? slotValue.trim()
|
|
: defaultSlotIdForKey("contextEngine");
|
|
|
|
const factory = getContextEngineRegistryState().engines.get(engineId);
|
|
if (!factory) {
|
|
throw new Error(
|
|
`Context engine "${engineId}" is not registered. ` +
|
|
`Available engines: ${listContextEngineIds().join(", ") || "(none)"}`,
|
|
);
|
|
}
|
|
|
|
return factory();
|
|
}
|