feat(mistral): add curated catalog models

This commit is contained in:
Vincent Koc 2026-03-22 17:55:24 -07:00
parent dc2013aae5
commit 45ede8729e
4 changed files with 126 additions and 5 deletions

View File

@ -1,7 +1,9 @@
import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
import { createProviderApiKeyAuthMethod } from "openclaw/plugin-sdk/provider-auth";
import { buildSingleProviderApiKeyCatalog } from "openclaw/plugin-sdk/provider-catalog";
import { mistralMediaUnderstandingProvider } from "./media-understanding-provider.js";
import { applyMistralConfig, MISTRAL_DEFAULT_MODEL_REF } from "./onboard.js";
import { buildMistralProvider } from "./provider-catalog.js";
const PROVIDER_ID = "mistral";
@ -37,6 +39,16 @@ export default definePluginEntry({
},
}),
],
catalog: {
order: "simple",
run: (ctx) =>
buildSingleProviderApiKeyCatalog({
ctx,
providerId: PROVIDER_ID,
buildProvider: buildMistralProvider,
allowExplicitBaseUrl: true,
}),
},
capabilities: {
transcriptToolCallIdMode: "strict9",
transcriptToolCallIdModelHints: [

View File

@ -1,5 +1,6 @@
import { describe, expect, it } from "vitest";
import {
buildMistralCatalogModels,
buildMistralModelDefinition,
MISTRAL_DEFAULT_CONTEXT_WINDOW,
MISTRAL_DEFAULT_COST,
@ -23,4 +24,30 @@ describe("mistral model definitions", () => {
cacheWrite: 0,
});
});
it("publishes a curated set of current Mistral catalog models", () => {
expect(buildMistralCatalogModels()).toEqual(
expect.arrayContaining([
expect.objectContaining({
id: "codestral-latest",
input: ["text"],
contextWindow: 256000,
maxTokens: 4096,
}),
expect.objectContaining({
id: "magistral-small",
reasoning: true,
input: ["text"],
contextWindow: 128000,
maxTokens: 128000,
}),
expect.objectContaining({
id: "pixtral-large-latest",
input: ["text", "image"],
contextWindow: 128000,
maxTokens: 128000,
}),
]),
);
});
});

View File

@ -12,14 +12,86 @@ export const MISTRAL_DEFAULT_COST = {
cacheWrite: 0,
};
export function buildMistralModelDefinition(): ModelDefinitionConfig {
return {
id: MISTRAL_DEFAULT_MODEL_ID,
name: "Mistral Large",
const MISTRAL_MODEL_CATALOG = [
{
id: "codestral-latest",
name: "Codestral (latest)",
reasoning: false,
input: ["text"],
cost: { input: 0.3, output: 0.9, cacheRead: 0, cacheWrite: 0 },
contextWindow: 256000,
maxTokens: 4096,
},
{
id: "devstral-medium-latest",
name: "Devstral 2 (latest)",
reasoning: false,
input: ["text"],
cost: { input: 0.4, output: 2, cacheRead: 0, cacheWrite: 0 },
contextWindow: 262144,
maxTokens: 262144,
},
{
id: "magistral-small",
name: "Magistral Small",
reasoning: true,
input: ["text"],
cost: { input: 0.5, output: 1.5, cacheRead: 0, cacheWrite: 0 },
contextWindow: 128000,
maxTokens: 128000,
},
{
id: "mistral-large-latest",
name: "Mistral Large (latest)",
reasoning: false,
input: ["text", "image"],
cost: MISTRAL_DEFAULT_COST,
contextWindow: MISTRAL_DEFAULT_CONTEXT_WINDOW,
maxTokens: MISTRAL_DEFAULT_MAX_TOKENS,
};
},
{
id: "mistral-medium-2508",
name: "Mistral Medium 3.1",
reasoning: false,
input: ["text", "image"],
cost: { input: 0.4, output: 2, cacheRead: 0, cacheWrite: 0 },
contextWindow: 262144,
maxTokens: 262144,
},
{
id: "mistral-small-latest",
name: "Mistral Small (latest)",
reasoning: false,
input: ["text", "image"],
cost: { input: 0.1, output: 0.3, cacheRead: 0, cacheWrite: 0 },
contextWindow: 128000,
maxTokens: 16384,
},
{
id: "pixtral-large-latest",
name: "Pixtral Large (latest)",
reasoning: false,
input: ["text", "image"],
cost: { input: 2, output: 6, cacheRead: 0, cacheWrite: 0 },
contextWindow: 128000,
maxTokens: 128000,
},
] as const satisfies readonly ModelDefinitionConfig[];
export function buildMistralModelDefinition(): ModelDefinitionConfig {
return (
MISTRAL_MODEL_CATALOG.find((model) => model.id === MISTRAL_DEFAULT_MODEL_ID) ?? {
id: MISTRAL_DEFAULT_MODEL_ID,
name: "Mistral Large",
reasoning: false,
input: ["text", "image"],
cost: MISTRAL_DEFAULT_COST,
contextWindow: MISTRAL_DEFAULT_CONTEXT_WINDOW,
maxTokens: MISTRAL_DEFAULT_MAX_TOKENS,
}
);
}
export function buildMistralCatalogModels(): ModelDefinitionConfig[] {
return MISTRAL_MODEL_CATALOG.map((model) => ({ ...model, input: [...model.input] }));
}

View File

@ -0,0 +1,10 @@
import type { ModelProviderConfig } from "openclaw/plugin-sdk/provider-models";
import { buildMistralCatalogModels, MISTRAL_BASE_URL } from "./model-definitions.js";
export function buildMistralProvider(): ModelProviderConfig {
return {
baseUrl: MISTRAL_BASE_URL,
api: "openai-completions",
models: buildMistralCatalogModels(),
};
}