mirror of
http://192.168.0.88:13333/lywsvip/openclaw-zero-token.git
synced 2026-06-20 12:13:00 +08:00
Major upgrade from e26988a38 to upstream v2026.3.28 (f9b107928).
Key changes:
- Upstream src/, ui/, extensions/ (89 bundled extensions)
- Zero-token web providers preserved in src/zero-token/
- AskOnce plugin restored and registered as CLI command
- Added missing packages: @anthropic-ai/vertex-sdk, @modelcontextprotocol/sdk
- Fixed tsconfig rootDir, skipLibCheck for plugin-sdk DTS build
- Added askonce to bundled plugin metadata and package.json exports
- Fixed AskOnce CLI command registration (missing commands metadata)
- Restored AskOnce adapter imports (correct 5-level relative paths)
- Removed stale migration artifacts from root directory
213 lines
6.3 KiB
TypeScript
213 lines
6.3 KiB
TypeScript
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
import type { OpenClawConfig } from "../config/config.js";
|
|
import { createEmptyPluginRegistry } from "../plugins/registry.js";
|
|
|
|
const { resolveRuntimePluginRegistryMock } = vi.hoisted(() => ({
|
|
resolveRuntimePluginRegistryMock: vi.fn<
|
|
(params?: unknown) => ReturnType<typeof createEmptyPluginRegistry> | undefined
|
|
>(() => undefined),
|
|
}));
|
|
|
|
vi.mock("../plugins/loader.js", () => ({
|
|
resolveRuntimePluginRegistry: resolveRuntimePluginRegistryMock,
|
|
}));
|
|
|
|
let generateImage: typeof import("./runtime.js").generateImage;
|
|
let listRuntimeImageGenerationProviders: typeof import("./runtime.js").listRuntimeImageGenerationProviders;
|
|
|
|
describe("image-generation runtime helpers", () => {
|
|
afterEach(() => {
|
|
resolveRuntimePluginRegistryMock.mockReset();
|
|
resolveRuntimePluginRegistryMock.mockReturnValue(undefined);
|
|
});
|
|
|
|
beforeEach(async () => {
|
|
vi.resetModules();
|
|
({ generateImage, listRuntimeImageGenerationProviders } = await import("./runtime.js"));
|
|
});
|
|
|
|
it("generates images through the active image-generation registry", async () => {
|
|
const pluginRegistry = createEmptyPluginRegistry();
|
|
const authStore = { version: 1, profiles: {} } as const;
|
|
let seenAuthStore: unknown;
|
|
pluginRegistry.imageGenerationProviders.push({
|
|
pluginId: "image-plugin",
|
|
pluginName: "Image Plugin",
|
|
source: "test",
|
|
provider: {
|
|
id: "image-plugin",
|
|
capabilities: {
|
|
generate: {},
|
|
edit: { enabled: false },
|
|
},
|
|
async generateImage(req) {
|
|
seenAuthStore = req.authStore;
|
|
return {
|
|
images: [
|
|
{
|
|
buffer: Buffer.from("png-bytes"),
|
|
mimeType: "image/png",
|
|
fileName: "sample.png",
|
|
},
|
|
],
|
|
model: "img-v1",
|
|
};
|
|
},
|
|
},
|
|
});
|
|
resolveRuntimePluginRegistryMock.mockReturnValue(pluginRegistry);
|
|
|
|
const cfg = {
|
|
agents: {
|
|
defaults: {
|
|
imageGenerationModel: {
|
|
primary: "image-plugin/img-v1",
|
|
},
|
|
},
|
|
},
|
|
} as OpenClawConfig;
|
|
|
|
const result = await generateImage({
|
|
cfg,
|
|
prompt: "draw a cat",
|
|
agentDir: "/tmp/agent",
|
|
authStore,
|
|
});
|
|
|
|
expect(result.provider).toBe("image-plugin");
|
|
expect(result.model).toBe("img-v1");
|
|
expect(result.attempts).toEqual([]);
|
|
expect(seenAuthStore).toEqual(authStore);
|
|
expect(result.images).toEqual([
|
|
{
|
|
buffer: Buffer.from("png-bytes"),
|
|
mimeType: "image/png",
|
|
fileName: "sample.png",
|
|
},
|
|
]);
|
|
});
|
|
|
|
it("lists runtime image-generation providers from the active registry", () => {
|
|
const pluginRegistry = createEmptyPluginRegistry();
|
|
pluginRegistry.imageGenerationProviders.push({
|
|
pluginId: "image-plugin",
|
|
pluginName: "Image Plugin",
|
|
source: "test",
|
|
provider: {
|
|
id: "image-plugin",
|
|
defaultModel: "img-v1",
|
|
models: ["img-v1", "img-v2"],
|
|
capabilities: {
|
|
generate: {
|
|
supportsResolution: true,
|
|
},
|
|
edit: {
|
|
enabled: true,
|
|
maxInputImages: 3,
|
|
},
|
|
geometry: {
|
|
resolutions: ["1K", "2K"],
|
|
},
|
|
},
|
|
generateImage: async () => ({
|
|
images: [{ buffer: Buffer.from("x"), mimeType: "image/png" }],
|
|
}),
|
|
},
|
|
});
|
|
resolveRuntimePluginRegistryMock.mockReturnValue(pluginRegistry);
|
|
|
|
expect(listRuntimeImageGenerationProviders()).toMatchObject([
|
|
{
|
|
id: "image-plugin",
|
|
defaultModel: "img-v1",
|
|
models: ["img-v1", "img-v2"],
|
|
capabilities: {
|
|
generate: {
|
|
supportsResolution: true,
|
|
},
|
|
edit: {
|
|
enabled: true,
|
|
maxInputImages: 3,
|
|
},
|
|
geometry: {
|
|
resolutions: ["1K", "2K"],
|
|
},
|
|
},
|
|
},
|
|
]);
|
|
});
|
|
|
|
it("explains native image-generation config and provider auth when no model is configured", async () => {
|
|
const pluginRegistry = createEmptyPluginRegistry();
|
|
pluginRegistry.imageGenerationProviders.push(
|
|
{
|
|
pluginId: "google",
|
|
pluginName: "Google",
|
|
source: "test",
|
|
provider: {
|
|
id: "google",
|
|
defaultModel: "gemini-3-pro-image-preview",
|
|
capabilities: {
|
|
generate: {},
|
|
edit: { enabled: false },
|
|
},
|
|
generateImage: async () => ({
|
|
images: [{ buffer: Buffer.from("x"), mimeType: "image/png" }],
|
|
}),
|
|
},
|
|
},
|
|
{
|
|
pluginId: "openai",
|
|
pluginName: "OpenAI",
|
|
source: "test",
|
|
provider: {
|
|
id: "openai",
|
|
defaultModel: "gpt-image-1",
|
|
capabilities: {
|
|
generate: {},
|
|
edit: { enabled: false },
|
|
},
|
|
generateImage: async () => ({
|
|
images: [{ buffer: Buffer.from("x"), mimeType: "image/png" }],
|
|
}),
|
|
},
|
|
},
|
|
);
|
|
resolveRuntimePluginRegistryMock.mockReturnValue(pluginRegistry);
|
|
|
|
const promise = generateImage({ cfg: {} as OpenClawConfig, prompt: "draw a cat" });
|
|
|
|
await expect(promise).rejects.toThrow("No image-generation model configured.");
|
|
await expect(promise).rejects.toThrow(
|
|
'Set agents.defaults.imageGenerationModel.primary to a provider/model like "',
|
|
);
|
|
await expect(promise).rejects.toThrow("google: GEMINI_API_KEY / GOOGLE_API_KEY");
|
|
await expect(promise).rejects.toThrow("openai: OPENAI_API_KEY");
|
|
});
|
|
|
|
it("does not crash on prototype-like provider ids in auth hints", async () => {
|
|
const pluginRegistry = createEmptyPluginRegistry();
|
|
pluginRegistry.imageGenerationProviders.push({
|
|
pluginId: "proto-provider",
|
|
pluginName: "Proto Provider",
|
|
source: "test",
|
|
provider: {
|
|
id: "__proto__",
|
|
defaultModel: "proto-v1",
|
|
capabilities: {
|
|
generate: {},
|
|
edit: { enabled: false },
|
|
},
|
|
generateImage: async () => ({
|
|
images: [{ buffer: Buffer.from("x"), mimeType: "image/png" }],
|
|
}),
|
|
},
|
|
});
|
|
resolveRuntimePluginRegistryMock.mockReturnValue(pluginRegistry);
|
|
|
|
await expect(
|
|
generateImage({ cfg: {} as OpenClawConfig, prompt: "draw a cat" }),
|
|
).rejects.toThrow("No image-generation model configured.");
|
|
});
|
|
});
|