openclaw/test/plugins/fireworks-model-alias.test.ts
Peter Steinberger 317f4755b8
fix(fireworks): replace the retired GLM 5.2 Fast default router (#160102)
Fireworks retired accounts/fireworks/routers/glm-5p2-fast. Onboarding, the bundled catalog and the curated live selector now use the documented GLM 5.3 Fast router (Fast cached-input price 0.39/M); explicit operator pins of the old id are preserved.

Forward-port of release/2026.9.7 066fd58ec8.
2026-09-27 22:19:45 -07:00

152 lines
5.6 KiB
TypeScript

import path from "node:path";
import { beforeEach, describe, expect, it, vi } from "vitest";
import type { OpenClawConfig } from "../../src/config/types.openclaw.js";
const manifestMocks = vi.hoisted(() => ({
getCurrentPluginMetadataSnapshot: vi.fn(),
loadPluginManifestRegistryCore: vi.fn(),
}));
vi.mock("../../src/plugins/current-plugin-metadata-snapshot.js", async (importOriginal) => ({
...(await importOriginal<
typeof import("../../src/plugins/current-plugin-metadata-snapshot.js")
>()),
getCurrentPluginMetadataSnapshot: manifestMocks.getCurrentPluginMetadataSnapshot,
}));
vi.mock("../../src/plugins/manifest-registry.js", async (importOriginal) => ({
...(await importOriginal<typeof import("../../src/plugins/manifest-registry.js")>()),
loadPluginManifestRegistryCore: manifestMocks.loadPluginManifestRegistryCore,
}));
import { resolveRuntimeHooks } from "../../src/agents/embedded-agent-runner/model.provider-hooks.js";
import { resolveModelWithRegistry } from "../../src/agents/embedded-agent-runner/model.registry-resolution.js";
import { resolveBundledStaticCatalogModel } from "../../src/agents/embedded-agent-runner/model.static-catalog.js";
import { loadPluginManifest } from "../../src/plugins/manifest.js";
import { clearPluginMetadataLifecycleCaches } from "../../src/plugins/plugin-metadata-lifecycle.js";
import { createPluginMetadataSnapshotFixture } from "../../src/plugins/plugin-metadata.test-support.js";
import { resolveOwningPluginIdsForProviderRef } from "../../src/plugins/providers.js";
import { resolveBundledPluginPublicModulePath } from "../../src/test-utils/bundled-plugin-public-surface.js";
beforeEach(() => {
clearPluginMetadataLifecycleCaches();
manifestMocks.getCurrentPluginMetadataSnapshot.mockReset();
manifestMocks.loadPluginManifestRegistryCore.mockReset();
});
describe("Fireworks manifest provider alias", () => {
const modelId = "accounts/fireworks/routers/glm-5p3-fast";
const providerBaseUrl = "https://fireworks-proxy.example/v1";
const modelBaseUrl = "https://fireworks-proxy.example/model";
beforeEach(() => {
const rootDir = path.dirname(
resolveBundledPluginPublicModulePath({
pluginId: "fireworks",
artifactBasename: "openclaw.plugin.json",
}),
);
const loaded = loadPluginManifest(rootDir);
if (!loaded.ok) {
throw new Error(loaded.error);
}
const snapshot = createPluginMetadataSnapshotFixture({
plugins: [{ ...loaded.manifest, origin: "bundled", rootDir }],
});
manifestMocks.getCurrentPluginMetadataSnapshot.mockReturnValue(snapshot);
manifestMocks.loadPluginManifestRegistryCore.mockReturnValue(snapshot.manifestRegistry);
});
function resolveFireworksGlm(provider: string, cfg?: OpenClawConfig) {
const catalogModel = resolveBundledStaticCatalogModel({
provider: "fireworks",
modelId,
includeRuntimeDiscovery: true,
});
if (!catalogModel) {
throw new Error("Missing Fireworks GLM catalog model");
}
return resolveModelWithRegistry({
provider,
modelId,
cfg,
modelRegistry: {
getAll: () => [catalogModel],
getAvailable: () => [],
hasConfiguredAuth: () => false,
find: (candidateProvider, candidateId) =>
candidateProvider === catalogModel.provider && candidateId === catalogModel.id
? catalogModel
: undefined,
},
runtimeHooks: resolveRuntimeHooks({ skipProviderRuntimeHooks: true }),
authProfileMode: "api_key",
});
}
it("finds the alias owner before runtime loading and resolves the canonical catalog model", async () => {
expect(resolveOwningPluginIdsForProviderRef({ provider: "fireworks-ai" })).toEqual([
"fireworks",
]);
const canonical = await resolveFireworksGlm("fireworks");
expect(canonical).toMatchObject({
provider: "fireworks",
id: modelId,
api: "openai-completions",
baseUrl: "https://api.fireworks.ai/inference/v1",
});
expect(await resolveFireworksGlm("fireworks-ai")).toEqual(canonical);
});
it.each([
["omitted API", undefined, undefined, undefined, "openai-completions"],
["provider API", "openai-responses", undefined, undefined, "openai-responses"],
[
"model API and URL",
"openai-responses",
"anthropic-messages",
modelBaseUrl,
"anthropic-messages",
],
] as const)(
"preserves explicit alias configuration with %s",
async (_name, providerApi, modelApi, configuredModelBaseUrl, expectedApi) => {
const cfg: OpenClawConfig = {
models: {
providers: {
"fireworks-ai": {
baseUrl: providerBaseUrl,
api: providerApi,
headers: { "X-Fireworks-Route": "custom" },
models: [
{
id: modelId,
name: "Configured GLM",
api: modelApi,
baseUrl: configuredModelBaseUrl,
reasoning: false,
input: ["text", "image"],
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
contextWindow: 4096,
maxTokens: 512,
},
],
},
},
},
};
expect(await resolveFireworksGlm("fireworks-ai", cfg)).toMatchObject({
provider: "fireworks-ai",
id: modelId,
api: expectedApi,
baseUrl: configuredModelBaseUrl ?? providerBaseUrl,
headers: { "X-Fireworks-Route": "custom" },
reasoning: false,
input: ["text", "image"],
contextWindow: 4096,
maxTokens: 512,
});
},
);
});