// Volcengine tests cover index plugin behavior. import { readFileSync } from "node:fs"; import { resolve } from "node:path"; import { registerSingleProviderPlugin } from "openclaw/plugin-sdk/plugin-test-runtime"; import { describe, expect, it } from "vitest"; import { VOLCENGINE_UNSUPPORTED_TOOL_SCHEMA_KEYWORDS } from "./api.js"; import plugin from "./index.js"; import { DOUBAO_CODING_MODEL_CATALOG, DOUBAO_MODEL_CATALOG } from "./models.js"; import { VOLCENGINE_PROVIDER_CATALOG } from "./models.js"; describe("volcengine plugin", () => { it("preserves both provider-owned static catalogs and paired ordering", async () => { const provider = await registerSingleProviderPlugin(plugin); expect(provider.catalog?.order).toBe("paired"); expect(provider.staticCatalog?.order).toBe("paired"); expect(await provider.staticCatalog?.run({} as never)).toEqual({ providers: Object.fromEntries( VOLCENGINE_PROVIDER_CATALOG.entries.map(({ id, buildProvider }) => [id, buildProvider()]), ), }); }); it("augments the catalog with bundled standard and plan models", async () => { const provider = await registerSingleProviderPlugin(plugin); expect(provider.auth?.[0]?.starterModel).toBe("volcengine-plan/ark-code-latest"); const entries = await provider.augmentModelCatalog?.({ env: process.env, entries: [], } as never); expect(entries).toEqual([ ...DOUBAO_MODEL_CATALOG.map((entry) => ({ provider: "volcengine", id: entry.id, name: entry.name, reasoning: entry.reasoning, input: [...entry.input], contextWindow: entry.contextWindow, })), ...DOUBAO_CODING_MODEL_CATALOG.map((entry) => ({ provider: "volcengine-plan", id: entry.id, name: entry.name, reasoning: entry.reasoning, input: [...entry.input], contextWindow: entry.contextWindow, })), ]); expect(DOUBAO_CODING_MODEL_CATALOG.map((entry) => entry.id)).toEqual([ "ark-code-latest", "doubao-seed-2.1-turbo", "glm-5.2", "deepseek-v4-pro", "deepseek-v4-flash", ]); }); it("declares its coding provider auth alias in the manifest", () => { const pluginJson = JSON.parse( readFileSync(resolve(import.meta.dirname, "openclaw.plugin.json"), "utf-8"), ); expect(pluginJson.providerAuthAliases).toEqual({ "volcengine-plan": "volcengine", }); }); it("declares OpenAI-compatible streaming usage support in the manifest", () => { const pluginJson = JSON.parse( readFileSync(resolve(import.meta.dirname, "openclaw.plugin.json"), "utf-8"), ); expect(pluginJson.providerRequest?.providers).toMatchObject({ volcengine: { openAICompletions: { supportsStreamingUsage: true }, }, "volcengine-plan": { openAICompletions: { supportsStreamingUsage: true }, }, }); }); it("marks direct and coding models with tool schema keyword compat", async () => { const provider = await registerSingleProviderPlugin(plugin); expect(provider.hookAliases).toContain("volcengine-plan"); const normalized = provider.normalizeResolvedModel?.({ provider: "volcengine-plan", modelId: "doubao-seed-2.1-turbo", model: { id: "doubao-seed-2.1-turbo", provider: "volcengine-plan", api: "openai-completions", compat: { unsupportedToolSchemaKeywords: ["not"] }, }, } as never); const normalizedCompat = normalized?.compat as | { unsupportedToolSchemaKeywords?: string[] } | undefined; expect(normalizedCompat?.unsupportedToolSchemaKeywords).toEqual([ "not", ...VOLCENGINE_UNSUPPORTED_TOOL_SCHEMA_KEYWORDS, ]); const normalizedAgain = provider.normalizeResolvedModel?.({ model: normalized } as never); expect(normalizedAgain).toBe(normalized); }); });