// Fireworks tests cover index plugin behavior. import type { ProviderRuntimeModel } from "openclaw/plugin-sdk/plugin-entry"; import { registerSingleProviderPlugin, resolveProviderPluginChoice, } from "openclaw/plugin-sdk/plugin-test-runtime"; import { describe, expect, it } from "vitest"; import { createProviderDynamicModelContext, runSingleProviderCatalog, } from "../test-support/provider-model-test-helpers.js"; import fireworksPlugin from "./index.js"; import { FIREWORKS_BASE_URL, FIREWORKS_DEFAULT_CONTEXT_WINDOW, FIREWORKS_DEFAULT_MAX_TOKENS, FIREWORKS_DEFAULT_MODEL_ID, } from "./provider-catalog.js"; import { resolveThinkingProfile } from "./provider-policy-api.js"; const FIREWORKS_KIMI_K2_6_MODEL_ID = "accounts/fireworks/models/kimi-k2p6"; function createFireworksDefaultRuntimeModel(params: { reasoning: boolean }): ProviderRuntimeModel { return { id: FIREWORKS_DEFAULT_MODEL_ID, name: FIREWORKS_DEFAULT_MODEL_ID, provider: "fireworks", api: "openai-completions", baseUrl: FIREWORKS_BASE_URL, reasoning: params.reasoning, input: ["text", "image"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: FIREWORKS_DEFAULT_CONTEXT_WINDOW, maxTokens: FIREWORKS_DEFAULT_MAX_TOKENS, }; } describe("fireworks provider plugin", () => { it("registers Fireworks with api-key auth wizard metadata", async () => { const provider = await registerSingleProviderPlugin(fireworksPlugin); const resolved = resolveProviderPluginChoice({ providers: [provider], choice: "fireworks-api-key", }); expect(provider.id).toBe("fireworks"); expect(provider.label).toBe("Fireworks"); expect(provider.aliases).toEqual(["fireworks-ai"]); expect(provider.envVars).toEqual(["FIREWORKS_API_KEY"]); expect(provider.auth).toHaveLength(1); if (!resolved) { throw new Error("expected Fireworks api-key auth choice"); } expect(resolved.provider.id).toBe("fireworks"); expect(resolved.method.id).toBe("api-key"); }); it("builds the Fireworks catalog", async () => { const provider = await registerSingleProviderPlugin(fireworksPlugin); const catalogProvider = await runSingleProviderCatalog(provider); expect(catalogProvider.api).toBe("openai-completions"); expect(catalogProvider.baseUrl).toBe(FIREWORKS_BASE_URL); const models = catalogProvider.models; if (!models) { throw new Error("expected Fireworks catalog models"); } expect(models.map((model) => model.id)).toEqual([ FIREWORKS_KIMI_K2_6_MODEL_ID, FIREWORKS_DEFAULT_MODEL_ID, ]); expect(models[0]?.reasoning).toBe(false); expect(models[0]?.input).toEqual(["text", "image"]); expect(models[0]?.contextWindow).toBe(262144); expect(models[0]?.maxTokens).toBe(262144); expect(models[1]?.reasoning).toBe(false); expect(models[1]?.input).toEqual(["text", "image"]); expect(models[1]?.contextWindow).toBe(FIREWORKS_DEFAULT_CONTEXT_WINDOW); expect(models[1]?.maxTokens).toBe(FIREWORKS_DEFAULT_MAX_TOKENS); }); it("resolves forward-compat Fireworks model ids from the default template", async () => { const provider = await registerSingleProviderPlugin(fireworksPlugin); const resolved = provider.resolveDynamicModel?.( createProviderDynamicModelContext({ provider: "fireworks", modelId: "accounts/fireworks/models/qwen3.6-plus", models: [createFireworksDefaultRuntimeModel({ reasoning: true })], }), ); expect(resolved?.provider).toBe("fireworks"); expect(resolved?.id).toBe("accounts/fireworks/models/qwen3.6-plus"); expect(resolved?.api).toBe("openai-completions"); expect(resolved?.baseUrl).toBe(FIREWORKS_BASE_URL); expect(resolved?.reasoning).toBe(true); expect(resolved?.input).toEqual(["text", "image"]); }); it("disables reasoning metadata for Fireworks Kimi dynamic models", async () => { const provider = await registerSingleProviderPlugin(fireworksPlugin); const resolved = provider.resolveDynamicModel?.( createProviderDynamicModelContext({ provider: "fireworks", modelId: "accounts/fireworks/models/kimi-k2p5", models: [createFireworksDefaultRuntimeModel({ reasoning: false })], }), ); expect(resolved?.provider).toBe("fireworks"); expect(resolved?.id).toBe("accounts/fireworks/models/kimi-k2p5"); expect(resolved?.reasoning).toBe(false); expect(resolved?.input).toEqual(["text", "image"]); }); it("keeps Fireworks GLM dynamic models text-only", async () => { const provider = await registerSingleProviderPlugin(fireworksPlugin); const resolved = provider.resolveDynamicModel?.( createProviderDynamicModelContext({ provider: "fireworks", modelId: "accounts/fireworks/models/glm-5p1", models: [createFireworksDefaultRuntimeModel({ reasoning: false })], }), ); expect(resolved?.provider).toBe("fireworks"); expect(resolved?.id).toBe("accounts/fireworks/models/glm-5p1"); expect(resolved?.input).toEqual(["text"]); }); it("disables reasoning metadata for Fireworks Kimi k2.5 aliases", async () => { const provider = await registerSingleProviderPlugin(fireworksPlugin); const resolved = provider.resolveDynamicModel?.( createProviderDynamicModelContext({ provider: "fireworks", modelId: "accounts/fireworks/routers/kimi-k2.5-turbo", models: [createFireworksDefaultRuntimeModel({ reasoning: false })], }), ); expect(resolved?.provider).toBe("fireworks"); expect(resolved?.id).toBe("accounts/fireworks/routers/kimi-k2.5-turbo"); expect(resolved?.reasoning).toBe(false); }); it("defers manifest catalog models to core static-catalog resolution", async () => { const provider = await registerSingleProviderPlugin(fireworksPlugin); for (const modelId of [FIREWORKS_KIMI_K2_6_MODEL_ID, FIREWORKS_DEFAULT_MODEL_ID]) { const resolved = provider.resolveDynamicModel?.( createProviderDynamicModelContext({ provider: "fireworks", modelId, models: [createFireworksDefaultRuntimeModel({ reasoning: false })], }), ); expect(resolved).toBeUndefined(); } }); it("exposes off-only thinking policy for Fireworks Kimi models", async () => { const provider = await registerSingleProviderPlugin(fireworksPlugin); expect( provider.resolveThinkingProfile?.({ provider: "fireworks", modelId: "accounts/fireworks/routers/kimi-k2p5-turbo", }), ).toEqual({ levels: [{ id: "off" }], defaultLevel: "off", }); expect( provider.resolveThinkingProfile?.({ provider: "fireworks", modelId: FIREWORKS_KIMI_K2_6_MODEL_ID, }), ).toEqual({ levels: [{ id: "off" }], defaultLevel: "off", }); expect( provider.resolveThinkingProfile?.({ provider: "fireworks", modelId: "accounts/fireworks/models/qwen3.6-plus", }), ).toBeUndefined(); expect(resolveThinkingProfile({ modelId: FIREWORKS_KIMI_K2_6_MODEL_ID })).toEqual({ levels: [{ id: "off" }], defaultLevel: "off", }); expect( resolveThinkingProfile({ modelId: "accounts/fireworks/models/qwen3.6-plus", }), ).toBeUndefined(); }); });