mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-24 20:53:04 +00:00
85 lines
2.5 KiB
TypeScript
85 lines
2.5 KiB
TypeScript
import { emitAgentEvent } from "../infra/agent-events.js";
|
|
import { normalizeOptionalString } from "../shared/string-coerce.js";
|
|
import {
|
|
isPluginJsonValue,
|
|
type PluginAgentEventEmitParams,
|
|
type PluginAgentEventEmitResult,
|
|
type PluginJsonValue,
|
|
} from "./host-hooks.js";
|
|
import type { PluginOrigin } from "./plugin-origin.types.js";
|
|
|
|
const HOST_OWNED_AGENT_EVENT_STREAMS = new Set<string>([
|
|
"lifecycle",
|
|
"tool",
|
|
"assistant",
|
|
"error",
|
|
"item",
|
|
"plan",
|
|
"approval",
|
|
"command_output",
|
|
"patch",
|
|
"compaction",
|
|
"thinking",
|
|
"model",
|
|
]);
|
|
|
|
function isPluginOwnedAgentEventStream(pluginId: string, stream: string): boolean {
|
|
return stream === pluginId || stream.startsWith(`${pluginId}.`);
|
|
}
|
|
|
|
function normalizePluginEventData(params: {
|
|
pluginId: string;
|
|
pluginName?: string;
|
|
data: PluginJsonValue;
|
|
}): Record<string, unknown> {
|
|
if (params.data && typeof params.data === "object" && !Array.isArray(params.data)) {
|
|
return {
|
|
...params.data,
|
|
pluginId: params.pluginId,
|
|
...(params.pluginName ? { pluginName: params.pluginName } : {}),
|
|
};
|
|
}
|
|
return {
|
|
value: params.data,
|
|
pluginId: params.pluginId,
|
|
...(params.pluginName ? { pluginName: params.pluginName } : {}),
|
|
};
|
|
}
|
|
|
|
export function emitPluginAgentEvent(params: {
|
|
pluginId: string;
|
|
pluginName?: string;
|
|
origin: PluginOrigin;
|
|
event: PluginAgentEventEmitParams;
|
|
}): PluginAgentEventEmitResult {
|
|
const runId = normalizeOptionalString(params.event.runId);
|
|
const sessionKey = normalizeOptionalString(params.event.sessionKey);
|
|
const stream = normalizeOptionalString(params.event.stream);
|
|
if (!runId || !stream) {
|
|
return { emitted: false, reason: "runId and stream are required" };
|
|
}
|
|
if (!isPluginJsonValue(params.event.data)) {
|
|
return { emitted: false, reason: "event data must be JSON-compatible" };
|
|
}
|
|
if (params.origin !== "bundled" && HOST_OWNED_AGENT_EVENT_STREAMS.has(stream)) {
|
|
return { emitted: false, reason: `stream ${stream} is reserved for bundled plugins` };
|
|
}
|
|
if (params.origin !== "bundled" && !isPluginOwnedAgentEventStream(params.pluginId, stream)) {
|
|
return {
|
|
emitted: false,
|
|
reason: `stream ${stream} must be scoped to plugin ${params.pluginId}`,
|
|
};
|
|
}
|
|
emitAgentEvent({
|
|
runId,
|
|
stream,
|
|
...(sessionKey ? { sessionKey } : {}),
|
|
data: normalizePluginEventData({
|
|
pluginId: params.pluginId,
|
|
pluginName: params.pluginName,
|
|
data: params.event.data,
|
|
}),
|
|
});
|
|
return { emitted: true, stream };
|
|
}
|