Skip to content
Merged
4 changes: 4 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,10 @@ LLM_GROQ_API_KEY=your_groq_key_here
# DeepSeek
LLM_DEEPSEEK_API_KEY=your_deepseek_key_here

# Xiaomi MiMo
LLM_XIAOMI_API_KEY=your_xiaomi_key_here
# LLM_XIAOMI_BASE_URL=https://api.xiaomimimo.com

# Perplexity
LLM_PERPLEXITY_API_KEY=your_perplexity_key_here

Expand Down
4 changes: 4 additions & 0 deletions .env.unified.example
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,10 @@ LLM_GROQ_API_KEY=your_groq_key_here
# DeepSeek
LLM_DEEPSEEK_API_KEY=your_deepseek_key_here

# Xiaomi MiMo
LLM_XIAOMI_API_KEY=your_xiaomi_key_here
# LLM_XIAOMI_BASE_URL=https://api.xiaomimimo.com

# Perplexity
LLM_PERPLEXITY_API_KEY=your_perplexity_key_here

Expand Down
1 change: 1 addition & 0 deletions .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ jobs:
LLM_EMBERCLOUD_API_KEY: ${{ secrets.LLM_EMBERCLOUD_API_KEY }}
LLM_ALIBABA_API_KEY__US_VIRGINIA: ${{ secrets.LLM_ALIBABA_API_KEY__US_VIRGINIA }}
LLM_ALIBABA_API_KEY__CN_BEIJING: ${{ secrets.LLM_ALIBABA_API_KEY__CN_BEIJING }}
LLM_XIAOMI_API_KEY: ${{ secrets.LLM_XIAOMI_API_KEY }}

- name: Upload shard results
if: always()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1304,6 +1304,7 @@ export function transformStreamingToOpenai(
case "bytedance":
case "minimax":
case "embercloud":
case "xiaomi":
case "azure-ai-foundry":
case "llmgateway": {
// Azure AI Foundry mirrors Azure OpenAI's prompt-filter-only leading
Expand Down
5 changes: 5 additions & 0 deletions apps/ui/src/components/provider-keys/provider-logo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,12 @@ export const providerLogoUrls: Partial<
nanogpt: ProviderIcons.nanogpt,
"aws-bedrock": ProviderIcons["aws-bedrock"],
azure: ProviderIcons.azure,
"azure-ai-foundry": ProviderIcons["azure-ai-foundry"],
cerebras: ProviderIcons.cerebras,
minimax: ProviderIcons.minimax,
bytedance: ProviderIcons.bytedance,
xiaomi: ProviderIcons.xiaomi,
embercloud: ProviderIcons.embercloud,
};

export const getProviderLogoDarkModeClasses = () => {
Expand Down
47 changes: 47 additions & 0 deletions packages/actions/src/get-provider-endpoint.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const originalVertexRegion = process.env.LLM_GOOGLE_VERTEX_REGION;
const originalAzureFoundryResource = process.env.LLM_AZURE_AI_FOUNDRY_RESOURCE;
const originalAzureFoundryApiVersion =
process.env.LLM_AZURE_AI_FOUNDRY_API_VERSION;
const originalXiaomiBaseUrl = process.env.LLM_XIAOMI_BASE_URL;

afterEach(() => {
if (originalAiStudioBaseUrl === undefined) {
Expand Down Expand Up @@ -54,6 +55,12 @@ afterEach(() => {
process.env.LLM_AZURE_AI_FOUNDRY_API_VERSION =
originalAzureFoundryApiVersion;
}

if (originalXiaomiBaseUrl === undefined) {
delete process.env.LLM_XIAOMI_BASE_URL;
} else {
process.env.LLM_XIAOMI_BASE_URL = originalXiaomiBaseUrl;
}
});

describe("getProviderEndpoint", () => {
Expand Down Expand Up @@ -249,6 +256,46 @@ describe("getProviderEndpoint", () => {
});
});

describe("xiaomi", () => {
it("builds the default Xiaomi endpoint", () => {
delete process.env.LLM_XIAOMI_BASE_URL;

const endpoint = getProviderEndpoint(
"xiaomi",
undefined,
"mimo-v2.5-pro",
);

expect(endpoint).toBe("https://api.xiaomimimo.com/v1/chat/completions");
});
Comment thread
coderabbitai[bot] marked this conversation as resolved.

it("uses custom base URL when provided", () => {
const endpoint = getProviderEndpoint(
"xiaomi",
"https://custom-xiaomi.example.com",
"mimo-v2-flash",
);

expect(endpoint).toBe(
"https://custom-xiaomi.example.com/v1/chat/completions",
);
});

it("builds streaming endpoint", () => {
delete process.env.LLM_XIAOMI_BASE_URL;

const endpoint = getProviderEndpoint(
"xiaomi",
undefined,
"mimo-v2.5",
undefined,
true,
);

expect(endpoint).toBe("https://api.xiaomimimo.com/v1/chat/completions");
});
});

describe("skipEnvVars (BYOK mode)", () => {
it("uses hardcoded default for google-ai-studio instead of env var", () => {
process.env.LLM_GOOGLE_AI_STUDIO_BASE_URL =
Expand Down
9 changes: 9 additions & 0 deletions packages/actions/src/get-provider-endpoint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,14 @@ export function getProviderEndpoint(
case "minimax":
url = "https://api.minimax.io";
break;
case "xiaomi":
url =
envValueOrDefault(
"xiaomi",
"baseUrl",
"https://api.xiaomimimo.com",
) ?? "https://api.xiaomimimo.com";
break;
case "aws-bedrock":
url =
envValueOrDefault(
Expand Down Expand Up @@ -487,6 +495,7 @@ export function getProviderEndpoint(
case "nebius":
case "nanogpt":
case "minimax":
case "xiaomi":
case "embercloud":
case "custom":
default:
Expand Down
2 changes: 2 additions & 0 deletions packages/models/src/models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { nousresearchModels } from "./models/nousresearch.js";
import { openaiModels } from "./models/openai.js";
import { perplexityModels } from "./models/perplexity.js";
import { xaiModels } from "./models/xai.js";
import { xiaomiModels } from "./models/xiaomi.js";
import { zaiModels } from "./models/zai.js";

import type { providers } from "./providers.js";
Expand Down Expand Up @@ -433,6 +434,7 @@ export const models = [
...googleModels,
...perplexityModels,
...xaiModels,
...xiaomiModels,
...metaModels,
...deepseekModels,
...mistralModels,
Expand Down
179 changes: 179 additions & 0 deletions packages/models/src/models/xiaomi.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
import type { ModelDefinition } from "@/models.js";

export const xiaomiModels = [
{
id: "mimo-v2.5-pro",
name: "MiMo V2.5 Pro",
description:
"Xiaomi's flagship 1T-parameter model with 42B activations, 1M ultra-long context, and deep thinking capabilities. Performs comparably to Claude Opus 4.6 in agent scenarios.",
family: "xiaomi",
releasedAt: new Date("2026-04-23"),
providers: [
{
providerId: "xiaomi" as const,
modelName: "mimo-v2.5-pro",
inputPrice: 1 / 1e6,
outputPrice: 3 / 1e6,
cachedInputPrice: 0.2 / 1e6,
requestPrice: 0,
contextSize: 1000000,
maxOutput: 131072,
streaming: true,
reasoning: true,
vision: false,
tools: true,
jsonOutput: true,
pricingTiers: [
{
name: "256K",
upToTokens: 256000,
inputPrice: 1 / 1e6,
outputPrice: 3 / 1e6,
cachedInputPrice: 0.2 / 1e6,
},
{
name: "1M",
upToTokens: 1000000,
inputPrice: 2 / 1e6,
outputPrice: 6 / 1e6,
cachedInputPrice: 0.4 / 1e6,
},
],
},
],
},
{
id: "mimo-v2-pro",
name: "MiMo V2 Pro",
description:
"Xiaomi's 1T-parameter model with 42B active parameters and 1M context window using hybrid Global Attention + SWA architecture.",
family: "xiaomi",
releasedAt: new Date("2026-03-18"),
providers: [
{
providerId: "xiaomi" as const,
modelName: "mimo-v2-pro",
inputPrice: 1 / 1e6,
outputPrice: 3 / 1e6,
cachedInputPrice: 0.2 / 1e6,
requestPrice: 0,
contextSize: 1000000,
maxOutput: 131072,
streaming: true,
reasoning: true,
vision: false,
tools: true,
jsonOutput: true,
pricingTiers: [
{
name: "256K",
upToTokens: 256000,
inputPrice: 1 / 1e6,
outputPrice: 3 / 1e6,
cachedInputPrice: 0.2 / 1e6,
},
{
name: "1M",
upToTokens: 1000000,
inputPrice: 2 / 1e6,
outputPrice: 6 / 1e6,
cachedInputPrice: 0.4 / 1e6,
},
],
},
],
},
{
id: "mimo-v2.5",
name: "MiMo V2.5",
description:
"Xiaomi's full-modal perception model supporting native understanding of images, videos, audio, and text with 1M context. Agent performance comparable to MiMo V2.5 Pro.",
family: "xiaomi",
releasedAt: new Date("2026-04-23"),
providers: [
{
providerId: "xiaomi" as const,
modelName: "mimo-v2.5",
inputPrice: 0.4 / 1e6,
outputPrice: 2 / 1e6,
cachedInputPrice: 0.08 / 1e6,
requestPrice: 0,
contextSize: 1000000,
maxOutput: 131072,
streaming: true,
reasoning: true,
vision: true,
tools: true,
jsonOutput: true,
pricingTiers: [
{
name: "256K",
upToTokens: 256000,
inputPrice: 0.4 / 1e6,
outputPrice: 2 / 1e6,
cachedInputPrice: 0.08 / 1e6,
},
{
name: "1M",
upToTokens: 1000000,
inputPrice: 0.8 / 1e6,
outputPrice: 4 / 1e6,
cachedInputPrice: 0.16 / 1e6,
},
],
},
],
},
{
id: "mimo-v2-omni",
name: "MiMo V2 Omni",
description:
"Xiaomi's multimodal model supporting text, vision, and speech modalities with 256K context window.",
family: "xiaomi",
releasedAt: new Date("2026-03-18"),
providers: [
{
providerId: "xiaomi" as const,
modelName: "mimo-v2-omni",
inputPrice: 0.4 / 1e6,
outputPrice: 2 / 1e6,
cachedInputPrice: 0.08 / 1e6,
requestPrice: 0,
contextSize: 256000,
maxOutput: 131072,
streaming: true,
reasoning: false,
vision: true,
tools: true,
jsonOutput: true,
},
],
},
{
id: "mimo-v2-flash",
name: "MiMo V2 Flash",
description:
"Xiaomi's high-efficiency inference model with hybrid architecture, 3 MTP layers for 2.5-3.7x faster inference, and 256K context.",
family: "xiaomi",
releasedAt: new Date("2025-12-16"),
providers: [
{
providerId: "xiaomi" as const,
modelName: "mimo-v2-flash",
inputPrice: 0.1 / 1e6,
outputPrice: 0.3 / 1e6,
// Flash model uses a 10% cache discount (not 20% like other MiMo models)
cachedInputPrice: 0.01 / 1e6,
requestPrice: 0,
contextSize: 256000,
maxOutput: undefined,
streaming: true,
reasoning: true,
reasoningOutput: "omit" as const,
vision: false,
tools: true,
jsonOutput: true,
},
Comment thread
analogpvt marked this conversation as resolved.
],
},
] as const satisfies ModelDefinition[];
19 changes: 19 additions & 0 deletions packages/models/src/providers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -566,6 +566,25 @@ export const providers = [
website: "https://www.embercloud.ai",
announcement: null,
},
{
id: "xiaomi",
name: "Xiaomi",
description:
"Xiaomi MiMo API Open Platform provides access to the MiMo series of large language models.",
env: {
required: {
apiKey: "LLM_XIAOMI_API_KEY",
},
optional: {
baseUrl: "LLM_XIAOMI_BASE_URL",
},
},
streaming: true,
cancellation: true,
color: "#FF6900",
website: "https://platform.xiaomimimo.com",
announcement: null,
},
] as const satisfies ProviderDefinition[];

export type ProviderId = (typeof providers)[number]["id"];
Expand Down
Loading
Loading