mirror of
https://fastgit.cc/github.com/openclaw/openclaw
synced 2026-05-01 15:42:39 +08:00
fix(plugins): treat context-engine plugins as capabilities in status/inspect (#58766)
Merged via squash.
Prepared head SHA: 23269d2db5
Co-authored-by: zhuisDEV <95547369+zhuisDEV@users.noreply.github.com>
Co-authored-by: jalehman <550978+jalehman@users.noreply.github.com>
Reviewed-by: @jalehman
This commit is contained in:
@@ -10,6 +10,7 @@ Docs: https://docs.openclaw.ai
|
||||
|
||||
- Agents/context engines: run opt-in turn maintenance as idle-aware background work so the next foreground turn no longer waits on proactive maintenance. (#65233) thanks @100yenadmin
|
||||
|
||||
- Plugins/status: report the registered context-engine IDs in `plugins inspect` instead of the owning plugin ID, so non-matching engine IDs and multi-engine plugins are classified correctly. (#58766) thanks @zhuisDEV
|
||||
## 2026.4.12
|
||||
|
||||
### Changes
|
||||
|
||||
@@ -2608,6 +2608,12 @@ module.exports = { id: "throws-after-import", register() {} };`,
|
||||
selectCount: () => 1,
|
||||
duplicateMessage:
|
||||
"context engine already registered: shared-context-engine-loader-test (plugin:context-engine-owner-a)",
|
||||
assertPrimaryOwner: (registry: ReturnType<typeof loadOpenClawPlugins>) => {
|
||||
expect(
|
||||
registry.plugins.find((entry) => entry.id === "context-engine-owner-a")
|
||||
?.contextEngineIds,
|
||||
).toEqual(["shared-context-engine-loader-test"]);
|
||||
},
|
||||
assert: expectDuplicateRegistrationResult,
|
||||
},
|
||||
{
|
||||
|
||||
@@ -733,6 +733,7 @@ function createPluginRecord(params: {
|
||||
musicGenerationProviderIds: [],
|
||||
webFetchProviderIds: [],
|
||||
webSearchProviderIds: [],
|
||||
contextEngineIds: [],
|
||||
memoryEmbeddingProviderIds: [],
|
||||
agentHarnessIds: [],
|
||||
gatewayMethods: [],
|
||||
|
||||
@@ -246,6 +246,7 @@ export type PluginRecord = {
|
||||
musicGenerationProviderIds: string[];
|
||||
webFetchProviderIds: string[];
|
||||
webSearchProviderIds: string[];
|
||||
contextEngineIds?: string[];
|
||||
memoryEmbeddingProviderIds: string[];
|
||||
agentHarnessIds: string[];
|
||||
gatewayMethods: string[];
|
||||
|
||||
@@ -1220,6 +1220,10 @@ export function createPluginRegistry(registryParams: PluginRegistryParams) {
|
||||
source: record.source,
|
||||
message: `context engine already registered: ${id} (${result.existingOwner})`,
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (!record.contextEngineIds?.includes(id)) {
|
||||
record.contextEngineIds = [...(record.contextEngineIds ?? []), id];
|
||||
}
|
||||
},
|
||||
registerCompactionProvider: (
|
||||
|
||||
@@ -59,6 +59,7 @@ export function createPluginRecord(
|
||||
musicGenerationProviderIds: [],
|
||||
webFetchProviderIds: [],
|
||||
webSearchProviderIds: [],
|
||||
contextEngineIds: [],
|
||||
memoryEmbeddingProviderIds: [],
|
||||
agentHarnessIds: [],
|
||||
gatewayMethods: [],
|
||||
|
||||
@@ -656,6 +656,32 @@ describe("plugin status reports", () => {
|
||||
expect(inspect.capabilities).toEqual([{ kind: "cli-backend", ids: ["claude-cli"] }]);
|
||||
});
|
||||
|
||||
it("treats a context-engine plugin as a plain capability", () => {
|
||||
setPluginLoadResult({
|
||||
plugins: [
|
||||
createPluginRecord({
|
||||
id: "moon",
|
||||
name: "Moon",
|
||||
kind: "context-engine",
|
||||
contextEngineIds: ["moon-engine"],
|
||||
hookCount: 1,
|
||||
}),
|
||||
],
|
||||
hooks: [createCustomHook({ pluginId: "moon", events: ["message"] })],
|
||||
});
|
||||
|
||||
const inspect = expectInspectReport("moon");
|
||||
|
||||
expectInspectShape(inspect, {
|
||||
shape: "plain-capability",
|
||||
capabilityMode: "plain",
|
||||
capabilityKinds: ["context-engine"],
|
||||
});
|
||||
expect(inspect.capabilities).toEqual([{ kind: "context-engine", ids: ["moon-engine"] }]);
|
||||
expect(inspect.compatibility).toEqual([]);
|
||||
expectNoCompatibilityWarnings();
|
||||
});
|
||||
|
||||
it("builds compatibility warnings for legacy compatibility paths", () => {
|
||||
setPluginLoadResult({
|
||||
plugins: [
|
||||
|
||||
@@ -21,6 +21,7 @@ import {
|
||||
resolvePluginRuntimeLoadContext,
|
||||
} from "./runtime/load-context.js";
|
||||
import { loadPluginMetadataRegistrySnapshot } from "./runtime/metadata-registry-loader.js";
|
||||
import { hasKind } from "./slots.js";
|
||||
import type { PluginHookName } from "./types.js";
|
||||
|
||||
export type PluginStatusReport = PluginRegistry & {
|
||||
@@ -37,6 +38,7 @@ export type PluginCapabilityKind =
|
||||
| "image-generation"
|
||||
| "web-search"
|
||||
| "agent-harness"
|
||||
| "context-engine"
|
||||
| "channel";
|
||||
|
||||
export type PluginInspectShape =
|
||||
@@ -249,6 +251,13 @@ function buildCapabilityEntries(plugin: PluginRegistry["plugins"][number]) {
|
||||
{ kind: "image-generation" as const, ids: plugin.imageGenerationProviderIds },
|
||||
{ kind: "web-search" as const, ids: plugin.webSearchProviderIds },
|
||||
{ kind: "agent-harness" as const, ids: plugin.agentHarnessIds },
|
||||
{
|
||||
kind: "context-engine" as const,
|
||||
ids:
|
||||
plugin.status === "loaded" && hasKind(plugin.kind, "context-engine")
|
||||
? (plugin.contextEngineIds ?? [])
|
||||
: [],
|
||||
},
|
||||
{ kind: "channel" as const, ids: plugin.channelIds },
|
||||
].filter((entry) => entry.ids.length > 0);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user