Files
openclaw/extensions/minimax/index.test.ts
2026-04-04 12:42:30 +01:00

180 lines
5.7 KiB
TypeScript

import type { StreamFn } from "@mariozechner/pi-agent-core";
import type { Context, Model } from "@mariozechner/pi-ai";
import { describe, expect, it, vi } from "vitest";
import {
registerProviderPlugin,
requireRegisteredProvider,
} from "../../test/helpers/plugins/provider-registration.js";
import minimaxPlugin from "./index.js";
describe("minimax provider hooks", () => {
it("keeps native reasoning mode for MiniMax transports", async () => {
const { providers } = await registerProviderPlugin({
plugin: minimaxPlugin,
id: "minimax",
name: "MiniMax Provider",
});
const apiProvider = requireRegisteredProvider(providers, "minimax");
const portalProvider = requireRegisteredProvider(providers, "minimax-portal");
expect(apiProvider.hookAliases).toContain("minimax-cn");
expect(
apiProvider.resolveReasoningOutputMode?.({
provider: "minimax",
modelApi: "anthropic-messages",
modelId: "MiniMax-M2.7",
} as never),
).toBe("native");
expect(portalProvider.hookAliases).toContain("minimax-portal-cn");
expect(
portalProvider.resolveReasoningOutputMode?.({
provider: "minimax-portal",
modelApi: "anthropic-messages",
modelId: "MiniMax-M2.7",
} as never),
).toBe("native");
});
it("owns replay policy for Anthropic and OpenAI-compatible MiniMax transports", async () => {
const { providers } = await registerProviderPlugin({
plugin: minimaxPlugin,
id: "minimax",
name: "MiniMax Provider",
});
const apiProvider = requireRegisteredProvider(providers, "minimax");
const portalProvider = requireRegisteredProvider(providers, "minimax-portal");
expect(
apiProvider.buildReplayPolicy?.({
provider: "minimax",
modelApi: "anthropic-messages",
modelId: "MiniMax-M2.7",
} as never),
).toMatchObject({
sanitizeMode: "full",
sanitizeToolCallIds: true,
preserveSignatures: true,
validateAnthropicTurns: true,
});
expect(
portalProvider.buildReplayPolicy?.({
provider: "minimax-portal",
modelApi: "openai-completions",
modelId: "MiniMax-M2.7",
} as never),
).toMatchObject({
sanitizeToolCallIds: true,
toolCallIdMode: "strict",
applyAssistantFirstOrderingFix: true,
validateGeminiTurns: true,
validateAnthropicTurns: true,
});
});
it("owns fast-mode stream wrapping for MiniMax transports", async () => {
const { providers } = await registerProviderPlugin({
plugin: minimaxPlugin,
id: "minimax",
name: "MiniMax Provider",
});
const apiProvider = requireRegisteredProvider(providers, "minimax");
const portalProvider = requireRegisteredProvider(providers, "minimax-portal");
let resolvedApiModelId = "";
const captureApiModel: StreamFn = (model) => {
resolvedApiModelId = String(model.id ?? "");
return {} as ReturnType<StreamFn>;
};
const wrappedApiStream = apiProvider.wrapStreamFn?.({
provider: "minimax",
modelId: "MiniMax-M2.7",
extraParams: { fastMode: true },
streamFn: captureApiModel,
} as never);
void wrappedApiStream?.(
{
api: "anthropic-messages",
provider: "minimax",
id: "MiniMax-M2.7",
} as Model<"anthropic-messages">,
{ messages: [] } as Context,
{},
);
let resolvedPortalModelId = "";
const capturePortalModel: StreamFn = (model) => {
resolvedPortalModelId = String(model.id ?? "");
return {} as ReturnType<StreamFn>;
};
const wrappedPortalStream = portalProvider.wrapStreamFn?.({
provider: "minimax-portal",
modelId: "MiniMax-M2.7",
extraParams: { fastMode: true },
streamFn: capturePortalModel,
} as never);
void wrappedPortalStream?.(
{
api: "anthropic-messages",
provider: "minimax-portal",
id: "MiniMax-M2.7",
} as Model<"anthropic-messages">,
{ messages: [] } as Context,
{},
);
expect(resolvedApiModelId).toBe("MiniMax-M2.7-highspeed");
expect(resolvedPortalModelId).toBe("MiniMax-M2.7-highspeed");
});
it("registers the bundled MiniMax web search provider", () => {
const webSearchProviders: unknown[] = [];
minimaxPlugin.register({
registerProvider() {},
registerMediaUnderstandingProvider() {},
registerImageGenerationProvider() {},
registerSpeechProvider() {},
registerWebSearchProvider(provider: unknown) {
webSearchProviders.push(provider);
},
} as never);
expect(webSearchProviders).toHaveLength(1);
expect(webSearchProviders[0]).toMatchObject({
id: "minimax",
label: "MiniMax Search",
envVars: ["MINIMAX_CODE_PLAN_KEY", "MINIMAX_CODING_API_KEY"],
});
});
it("prefers minimax-portal oauth when resolving MiniMax usage auth", async () => {
const { providers } = await registerProviderPlugin({
plugin: minimaxPlugin,
id: "minimax",
name: "MiniMax Provider",
});
const apiProvider = requireRegisteredProvider(providers, "minimax");
const resolveOAuthToken = vi.fn(async (params?: { provider?: string }) =>
params?.provider === "minimax-portal" ? { token: "portal-oauth-token" } : null,
);
const resolveApiKeyFromConfigAndStore = vi.fn(() => undefined);
await expect(
apiProvider.resolveUsageAuth?.({
provider: "minimax",
config: {},
env: {},
resolveOAuthToken,
resolveApiKeyFromConfigAndStore,
} as never),
).resolves.toEqual({ token: "portal-oauth-token" });
expect(resolveOAuthToken).toHaveBeenCalledWith({ provider: "minimax-portal" });
expect(resolveApiKeyFromConfigAndStore).not.toHaveBeenCalled();
});
});