mirror of https://github.com/openclaw/openclaw.git
152 lines
4.7 KiB
TypeScript
152 lines
4.7 KiB
TypeScript
import fs from "node:fs/promises";
|
|
import os from "node:os";
|
|
import path from "node:path";
|
|
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
import type { OpenClawConfig } from "../config/config.js";
|
|
import {
|
|
withBundledPluginAllowlistCompat,
|
|
withBundledPluginEnablementCompat,
|
|
withBundledPluginVitestCompat,
|
|
} from "../plugins/bundled-compat.js";
|
|
import { __testing as loaderTesting } from "../plugins/loader.js";
|
|
import { loadPluginManifestRegistry } from "../plugins/manifest-registry.js";
|
|
import { createEmptyPluginRegistry } from "../plugins/registry.js";
|
|
import { setActivePluginRegistry } from "../plugins/runtime.js";
|
|
|
|
let describeImageFile: typeof import("./runtime.js").describeImageFile;
|
|
let runMediaUnderstandingFile: typeof import("./runtime.js").runMediaUnderstandingFile;
|
|
let resolveRuntimePluginRegistryMock: ReturnType<
|
|
typeof vi.fn<(params?: unknown) => ReturnType<typeof createEmptyPluginRegistry> | undefined>
|
|
>;
|
|
|
|
function setCompatibleActiveMediaUnderstandingRegistry(
|
|
pluginRegistry: ReturnType<typeof createEmptyPluginRegistry>,
|
|
cfg: OpenClawConfig,
|
|
) {
|
|
const pluginIds = loadPluginManifestRegistry({
|
|
config: cfg,
|
|
env: process.env,
|
|
})
|
|
.plugins.filter(
|
|
(plugin) =>
|
|
plugin.origin === "bundled" &&
|
|
(plugin.contracts?.mediaUnderstandingProviders?.length ?? 0) > 0,
|
|
)
|
|
.map((plugin) => plugin.id)
|
|
.toSorted((left, right) => left.localeCompare(right));
|
|
const compatibleConfig = withBundledPluginVitestCompat({
|
|
config: withBundledPluginEnablementCompat({
|
|
config: withBundledPluginAllowlistCompat({
|
|
config: cfg,
|
|
pluginIds,
|
|
}),
|
|
pluginIds,
|
|
}),
|
|
pluginIds,
|
|
env: process.env,
|
|
});
|
|
const { cacheKey } = loaderTesting.resolvePluginLoadCacheContext({
|
|
config: compatibleConfig,
|
|
env: process.env,
|
|
});
|
|
setActivePluginRegistry(pluginRegistry, cacheKey);
|
|
}
|
|
|
|
describe("media-understanding runtime helpers", () => {
|
|
afterEach(() => {
|
|
resolveRuntimePluginRegistryMock.mockReset();
|
|
resolveRuntimePluginRegistryMock.mockReturnValue(undefined);
|
|
vi.doUnmock("../plugins/loader.js");
|
|
});
|
|
|
|
beforeEach(async () => {
|
|
vi.resetModules();
|
|
resolveRuntimePluginRegistryMock = vi.fn<
|
|
(params?: unknown) => ReturnType<typeof createEmptyPluginRegistry> | undefined
|
|
>(() => undefined);
|
|
vi.doMock("../plugins/loader.js", () => ({
|
|
resolveRuntimePluginRegistry: resolveRuntimePluginRegistryMock,
|
|
}));
|
|
({ describeImageFile, runMediaUnderstandingFile } = await import("./runtime.js"));
|
|
});
|
|
|
|
it("describes images through the active media-understanding registry", async () => {
|
|
const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-media-runtime-"));
|
|
const imagePath = path.join(tempDir, "sample.jpg");
|
|
await fs.writeFile(imagePath, Buffer.from("image-bytes"));
|
|
|
|
const pluginRegistry = createEmptyPluginRegistry();
|
|
pluginRegistry.mediaUnderstandingProviders.push({
|
|
pluginId: "vision-plugin",
|
|
pluginName: "Vision Plugin",
|
|
source: "test",
|
|
provider: {
|
|
id: "vision-plugin",
|
|
capabilities: ["image"],
|
|
describeImage: async () => ({ text: "image ok", model: "vision-v1" }),
|
|
},
|
|
});
|
|
resolveRuntimePluginRegistryMock.mockReturnValue(pluginRegistry);
|
|
|
|
const cfg = {
|
|
tools: {
|
|
media: {
|
|
image: {
|
|
models: [{ provider: "vision-plugin", model: "vision-v1" }],
|
|
},
|
|
},
|
|
},
|
|
} as OpenClawConfig;
|
|
setCompatibleActiveMediaUnderstandingRegistry(pluginRegistry, cfg);
|
|
|
|
const result = await describeImageFile({
|
|
filePath: imagePath,
|
|
mime: "image/jpeg",
|
|
cfg,
|
|
agentDir: "/tmp/agent",
|
|
});
|
|
|
|
expect(result).toEqual({
|
|
text: "image ok",
|
|
provider: "vision-plugin",
|
|
model: "vision-v1",
|
|
output: {
|
|
kind: "image.description",
|
|
attachmentIndex: 0,
|
|
text: "image ok",
|
|
provider: "vision-plugin",
|
|
model: "vision-v1",
|
|
},
|
|
});
|
|
});
|
|
|
|
it("returns undefined when no media output is produced", async () => {
|
|
const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-media-runtime-"));
|
|
const imagePath = path.join(tempDir, "sample.jpg");
|
|
await fs.writeFile(imagePath, Buffer.from("image-bytes"));
|
|
|
|
const result = await runMediaUnderstandingFile({
|
|
capability: "image",
|
|
filePath: imagePath,
|
|
mime: "image/jpeg",
|
|
cfg: {
|
|
tools: {
|
|
media: {
|
|
image: {
|
|
enabled: false,
|
|
},
|
|
},
|
|
},
|
|
} as OpenClawConfig,
|
|
agentDir: "/tmp/agent",
|
|
});
|
|
|
|
expect(result).toEqual({
|
|
text: undefined,
|
|
provider: undefined,
|
|
model: undefined,
|
|
output: undefined,
|
|
});
|
|
});
|
|
});
|