Files
openclaw/src/config/config.identity-defaults.test.ts
liyuan97 b64f4e313d MiniMax: add M2.7 models and update default to M2.7 (#49691)
* MiniMax: add M2.7 models and update default to M2.7

- Add MiniMax-M2.7 and MiniMax-M2.7-highspeed to provider catalog and model definitions
- Update default model from MiniMax-M2.5 to MiniMax-M2.7 across onboard, portal, and provider configs
- Update isModernMiniMaxModel to recognize M2.7 prefix
- Update all test fixtures to reflect M2.7 as default

Made-with: Cursor

* MiniMax: add extension test for model definitions

* update 2.7

* feat: add MiniMax M2.7 models and update default (#49691) (thanks @liyuan97)

---------

Co-authored-by: George Zhang <georgezhangtj97@gmail.com>
2026-03-18 09:24:37 -07:00

194 lines
6.4 KiB
TypeScript

import fs from "node:fs/promises";
import path from "node:path";
import { describe, expect, it } from "vitest";
import { DEFAULT_AGENT_MAX_CONCURRENT, DEFAULT_SUBAGENT_MAX_CONCURRENT } from "./agent-limits.js";
import { loadConfig } from "./config.js";
import { withTempHome } from "./home-env.test-harness.js";
describe("config identity defaults", () => {
const defaultIdentity = {
name: "Samantha",
theme: "helpful sloth",
emoji: "🦥",
};
const configWithDefaultIdentity = (messages: Record<string, unknown>) => ({
agents: {
list: [
{
id: "main",
identity: defaultIdentity,
},
],
},
messages,
});
const writeAndLoadConfig = async (home: string, config: Record<string, unknown>) => {
const configDir = path.join(home, ".openclaw");
await fs.mkdir(configDir, { recursive: true });
await fs.writeFile(
path.join(configDir, "openclaw.json"),
JSON.stringify(config, null, 2),
"utf-8",
);
return loadConfig();
};
it("does not derive mention defaults and only sets ackReactionScope when identity is present", async () => {
await withTempHome("openclaw-config-identity-", async (home) => {
const cfg = await writeAndLoadConfig(home, configWithDefaultIdentity({}));
expect(cfg.messages?.responsePrefix).toBeUndefined();
expect(cfg.messages?.groupChat?.mentionPatterns).toBeUndefined();
expect(cfg.messages?.ackReaction).toBeUndefined();
expect(cfg.messages?.ackReactionScope).toBe("group-mentions");
});
});
it("keeps ackReaction unset and does not synthesize agent/session defaults when identity is missing", async () => {
await withTempHome("openclaw-config-identity-", async (home) => {
const cfg = await writeAndLoadConfig(home, { messages: {} });
expect(cfg.messages?.ackReaction).toBeUndefined();
expect(cfg.messages?.ackReactionScope).toBe("group-mentions");
expect(cfg.messages?.responsePrefix).toBeUndefined();
expect(cfg.messages?.groupChat?.mentionPatterns).toBeUndefined();
expect(cfg.agents?.list).toBeUndefined();
expect(cfg.agents?.defaults?.maxConcurrent).toBe(DEFAULT_AGENT_MAX_CONCURRENT);
expect(cfg.agents?.defaults?.subagents?.maxConcurrent).toBe(DEFAULT_SUBAGENT_MAX_CONCURRENT);
expect(cfg.session).toBeUndefined();
});
});
it("does not override explicit values", async () => {
await withTempHome("openclaw-config-identity-", async (home) => {
const cfg = await writeAndLoadConfig(home, {
agents: {
list: [
{
id: "main",
identity: {
name: "Samantha Sloth",
theme: "space lobster",
emoji: "🦞",
},
groupChat: { mentionPatterns: ["@openclaw"] },
},
],
},
messages: {
responsePrefix: "✅",
},
});
expect(cfg.messages?.responsePrefix).toBe("✅");
expect(cfg.agents?.list?.[0]?.groupChat?.mentionPatterns).toEqual(["@openclaw"]);
});
});
it("supports provider textChunkLimit config", async () => {
await withTempHome("openclaw-config-identity-", async (home) => {
const cfg = await writeAndLoadConfig(home, {
messages: {
messagePrefix: "[openclaw]",
responsePrefix: "🦞",
},
channels: {
whatsapp: { allowFrom: ["+15555550123"], textChunkLimit: 4444 },
telegram: { enabled: true, textChunkLimit: 3333 },
discord: {
enabled: true,
textChunkLimit: 1999,
maxLinesPerMessage: 17,
},
signal: { enabled: true, textChunkLimit: 2222 },
imessage: { enabled: true, textChunkLimit: 1111 },
},
});
expect(cfg.channels?.whatsapp?.textChunkLimit).toBe(4444);
expect(cfg.channels?.telegram?.textChunkLimit).toBe(3333);
expect(cfg.channels?.discord?.textChunkLimit).toBe(1999);
expect(cfg.channels?.discord?.maxLinesPerMessage).toBe(17);
expect(cfg.channels?.signal?.textChunkLimit).toBe(2222);
expect(cfg.channels?.imessage?.textChunkLimit).toBe(1111);
const legacy = (cfg.messages as unknown as Record<string, unknown>).textChunkLimit;
expect(legacy).toBeUndefined();
});
});
it("accepts blank model provider apiKey values", async () => {
await withTempHome("openclaw-config-identity-", async (home) => {
const cfg = await writeAndLoadConfig(home, {
models: {
mode: "merge",
providers: {
minimax: {
baseUrl: "https://api.minimax.io/anthropic",
apiKey: "",
api: "anthropic-messages",
models: [
{
id: "MiniMax-M2.7",
name: "MiniMax M2.7",
reasoning: false,
input: ["text"],
cost: {
input: 0,
output: 0,
cacheRead: 0,
cacheWrite: 0,
},
contextWindow: 200000,
maxTokens: 8192,
},
],
},
},
},
});
expect(cfg.models?.providers?.minimax?.baseUrl).toBe("https://api.minimax.io/anthropic");
});
});
it("accepts SecretRef values in model provider headers", async () => {
await withTempHome("openclaw-config-identity-", async (home) => {
const cfg = await writeAndLoadConfig(home, {
models: {
providers: {
openai: {
baseUrl: "https://api.openai.com/v1",
api: "openai-completions",
headers: {
Authorization: {
source: "env",
provider: "default",
id: "OPENAI_HEADER_TOKEN",
},
},
models: [],
},
},
},
});
expect(cfg.models?.providers?.openai?.headers?.Authorization).toEqual({
source: "env",
provider: "default",
id: "OPENAI_HEADER_TOKEN",
});
});
});
it("respects empty responsePrefix to disable identity defaults", async () => {
await withTempHome("openclaw-config-identity-", async (home) => {
const cfg = await writeAndLoadConfig(home, configWithDefaultIdentity({ responsePrefix: "" }));
expect(cfg.messages?.responsePrefix).toBe("");
});
});
});