mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-25 08:52:12 +00:00
Context: extract extension host engine runtime
This commit is contained in:
@@ -1,5 +1,10 @@
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import { defaultSlotIdForKey } from "../plugins/slots.js";
|
||||
import {
|
||||
getExtensionHostContextEngineFactory,
|
||||
listExtensionHostContextEngineIds,
|
||||
registerExtensionHostContextEngine,
|
||||
resolveExtensionHostContextEngine,
|
||||
type ExtensionHostContextEngineFactory,
|
||||
} from "../extension-host/context-engine-runtime.js";
|
||||
import type { ContextEngine } from "./types.js";
|
||||
|
||||
/**
|
||||
@@ -97,18 +102,12 @@ export function registerContextEngine(
|
||||
return registerContextEngineForOwner(id, factory, PUBLIC_CONTEXT_ENGINE_OWNER);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the factory for a registered engine, or undefined.
|
||||
*/
|
||||
export function getContextEngineFactory(id: string): ContextEngineFactory | undefined {
|
||||
return getContextEngineRegistryState().engines.get(id)?.factory;
|
||||
}
|
||||
|
||||
/**
|
||||
* List all registered engine ids.
|
||||
*/
|
||||
export function listContextEngineIds(): string[] {
|
||||
return [...getContextEngineRegistryState().engines.keys()];
|
||||
return listExtensionHostContextEngineIds();
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
42
src/extension-host/context-engine-runtime.test.ts
Normal file
42
src/extension-host/context-engine-runtime.test.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import type { ContextEngine } from "../context-engine/types.js";
|
||||
import {
|
||||
getExtensionHostContextEngineFactory,
|
||||
listExtensionHostContextEngineIds,
|
||||
registerExtensionHostContextEngine,
|
||||
} from "./context-engine-runtime.js";
|
||||
|
||||
class TestContextEngine implements ContextEngine {
|
||||
readonly info = {
|
||||
id: "host-test",
|
||||
name: "Host Test",
|
||||
version: "1.0.0",
|
||||
};
|
||||
|
||||
async ingest() {
|
||||
return { ingested: false };
|
||||
}
|
||||
|
||||
async assemble(params: { messages: [] }) {
|
||||
return { messages: params.messages, estimatedTokens: 0 };
|
||||
}
|
||||
|
||||
async afterTurn() {}
|
||||
|
||||
async compact() {
|
||||
return { ok: true, compacted: false, reason: "noop" };
|
||||
}
|
||||
}
|
||||
|
||||
describe("extension host context engine runtime", () => {
|
||||
it("stores registered context-engine factories in the host-owned runtime", async () => {
|
||||
const factory = () => new TestContextEngine();
|
||||
registerExtensionHostContextEngine("host-test", factory);
|
||||
|
||||
expect(getExtensionHostContextEngineFactory("host-test")).toBe(factory);
|
||||
expect(listExtensionHostContextEngineIds()).toContain("host-test");
|
||||
expect(await getExtensionHostContextEngineFactory("host-test")?.()).toBeInstanceOf(
|
||||
TestContextEngine,
|
||||
);
|
||||
});
|
||||
});
|
||||
60
src/extension-host/context-engine-runtime.ts
Normal file
60
src/extension-host/context-engine-runtime.ts
Normal file
@@ -0,0 +1,60 @@
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import type { ContextEngine } from "../context-engine/types.js";
|
||||
import { defaultSlotIdForKey } from "../plugins/slots.js";
|
||||
|
||||
export type ExtensionHostContextEngineFactory = () => ContextEngine | Promise<ContextEngine>;
|
||||
|
||||
const CONTEXT_ENGINE_RUNTIME_STATE = Symbol.for("openclaw.contextEngineRegistryState");
|
||||
|
||||
type ExtensionHostContextEngineRuntimeState = {
|
||||
engines: Map<string, ExtensionHostContextEngineFactory>;
|
||||
};
|
||||
|
||||
function getExtensionHostContextEngineRuntimeState(): ExtensionHostContextEngineRuntimeState {
|
||||
const globalState = globalThis as typeof globalThis & {
|
||||
[CONTEXT_ENGINE_RUNTIME_STATE]?: ExtensionHostContextEngineRuntimeState;
|
||||
};
|
||||
if (!globalState[CONTEXT_ENGINE_RUNTIME_STATE]) {
|
||||
globalState[CONTEXT_ENGINE_RUNTIME_STATE] = {
|
||||
engines: new Map<string, ExtensionHostContextEngineFactory>(),
|
||||
};
|
||||
}
|
||||
return globalState[CONTEXT_ENGINE_RUNTIME_STATE];
|
||||
}
|
||||
|
||||
export function registerExtensionHostContextEngine(
|
||||
id: string,
|
||||
factory: ExtensionHostContextEngineFactory,
|
||||
): void {
|
||||
getExtensionHostContextEngineRuntimeState().engines.set(id, factory);
|
||||
}
|
||||
|
||||
export function getExtensionHostContextEngineFactory(
|
||||
id: string,
|
||||
): ExtensionHostContextEngineFactory | undefined {
|
||||
return getExtensionHostContextEngineRuntimeState().engines.get(id);
|
||||
}
|
||||
|
||||
export function listExtensionHostContextEngineIds(): string[] {
|
||||
return [...getExtensionHostContextEngineRuntimeState().engines.keys()];
|
||||
}
|
||||
|
||||
export async function resolveExtensionHostContextEngine(
|
||||
config?: OpenClawConfig,
|
||||
): Promise<ContextEngine> {
|
||||
const slotValue = config?.plugins?.slots?.contextEngine;
|
||||
const engineId =
|
||||
typeof slotValue === "string" && slotValue.trim()
|
||||
? slotValue.trim()
|
||||
: defaultSlotIdForKey("contextEngine");
|
||||
|
||||
const factory = getExtensionHostContextEngineRuntimeState().engines.get(engineId);
|
||||
if (!factory) {
|
||||
throw new Error(
|
||||
`Context engine "${engineId}" is not registered. ` +
|
||||
`Available engines: ${listExtensionHostContextEngineIds().join(", ") || "(none)"}`,
|
||||
);
|
||||
}
|
||||
|
||||
return factory();
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
import type { AnyAgentTool } from "../agents/tools/common.js";
|
||||
import type { ChannelPlugin } from "../channels/plugins/types.js";
|
||||
import { registerContextEngine as registerLegacyContextEngine } from "../context-engine/registry.js";
|
||||
import type { GatewayRequestHandler } from "../gateway/server-methods/types.js";
|
||||
import { registerInternalHook } from "../hooks/internal-hooks.js";
|
||||
import type { PluginRecord, PluginRegistry } from "../plugins/registry.js";
|
||||
@@ -16,6 +15,7 @@ import type {
|
||||
OpenClawPluginToolFactory,
|
||||
PluginHookRegistration as TypedPluginHookRegistration,
|
||||
} from "../plugins/types.js";
|
||||
import { registerExtensionHostContextEngine } from "./context-engine-runtime.js";
|
||||
import {
|
||||
applyExtensionHostTypedHookPolicy,
|
||||
bridgeExtensionHostLegacyHooks,
|
||||
@@ -307,7 +307,7 @@ export function createExtensionHostPluginRegistrationActions(params: {
|
||||
const registerContextEngine = (
|
||||
record: PluginRecord,
|
||||
engineId: string,
|
||||
factory: Parameters<typeof registerLegacyContextEngine>[1],
|
||||
factory: Parameters<typeof registerExtensionHostContextEngine>[1],
|
||||
) => {
|
||||
const result = resolveExtensionContextEngineRegistration({
|
||||
engineId,
|
||||
@@ -325,7 +325,7 @@ export function createExtensionHostPluginRegistrationActions(params: {
|
||||
}
|
||||
addExtensionContextEngineRegistration({
|
||||
entry: result.entry,
|
||||
registerEngine: registerLegacyContextEngine,
|
||||
registerEngine: registerExtensionHostContextEngine,
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { registerContextEngine, type ContextEngineFactory } from "../context-engine/registry.js";
|
||||
import type { GatewayRequestHandler } from "../gateway/server-methods/types.js";
|
||||
import type {
|
||||
PluginChannelRegistration,
|
||||
@@ -13,6 +12,10 @@ import type {
|
||||
PluginToolRegistration,
|
||||
} from "../plugins/registry.js";
|
||||
import type { PluginHookRegistration as TypedPluginHookRegistration } from "../plugins/types.js";
|
||||
import {
|
||||
registerExtensionHostContextEngine,
|
||||
type ExtensionHostContextEngineFactory,
|
||||
} from "./context-engine-runtime.js";
|
||||
import type {
|
||||
ExtensionHostChannelRegistration,
|
||||
ExtensionHostCliRegistration,
|
||||
@@ -162,8 +165,8 @@ export function addExtensionCommandRegistration(params: {
|
||||
|
||||
export function addExtensionContextEngineRegistration(params: {
|
||||
entry: ExtensionHostContextEngineRegistration;
|
||||
registerEngine?: (engineId: string, factory: ContextEngineFactory) => void;
|
||||
registerEngine?: (engineId: string, factory: ExtensionHostContextEngineFactory) => void;
|
||||
}): void {
|
||||
const registerEngine = params.registerEngine ?? registerContextEngine;
|
||||
const registerEngine = params.registerEngine ?? registerExtensionHostContextEngine;
|
||||
registerEngine(params.entry.engineId, params.entry.factory);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user