From 129d5be5073d36d73ff138b15cbfa833ac3201f4 Mon Sep 17 00:00:00 2001 From: Shakker Date: Tue, 28 Apr 2026 03:36:51 +0100 Subject: [PATCH] refactor: build cerebras and mistral catalogs from manifests --- extensions/cerebras/models.ts | 58 ++++-------- extensions/cerebras/provider-catalog.ts | 8 +- extensions/mistral/model-definitions.ts | 115 ++++++------------------ extensions/mistral/provider-catalog.ts | 12 +-- 4 files changed, 52 insertions(+), 141 deletions(-) diff --git a/extensions/cerebras/models.ts b/extensions/cerebras/models.ts index 228b722f8e8..cde8ad15a6d 100644 --- a/extensions/cerebras/models.ts +++ b/extensions/cerebras/models.ts @@ -1,49 +1,25 @@ +import { buildManifestModelProviderConfig } from "openclaw/plugin-sdk/provider-catalog-shared"; import type { ModelDefinitionConfig } from "openclaw/plugin-sdk/provider-model-shared"; +import manifest from "./openclaw.plugin.json" with { type: "json" }; -export const CEREBRAS_BASE_URL = "https://api.cerebras.ai/v1"; +const CEREBRAS_MANIFEST_CATALOG = manifest.modelCatalog.providers.cerebras; -export const CEREBRAS_MODEL_CATALOG = [ - { - id: "zai-glm-4.7", - name: "Z.ai GLM 4.7", - reasoning: true, - input: ["text"], - cost: { input: 2.25, output: 2.75, cacheRead: 2.25, cacheWrite: 2.75 }, - }, - { - id: "gpt-oss-120b", - name: "GPT OSS 120B", - reasoning: true, - input: ["text"], - cost: { input: 0.35, output: 0.75, cacheRead: 0.35, cacheWrite: 0.75 }, - }, - { - id: "qwen-3-235b-a22b-instruct-2507", - name: "Qwen 3 235B Instruct", - reasoning: false, - input: ["text"], - cost: { input: 0.6, output: 1.2, cacheRead: 0.6, cacheWrite: 1.2 }, - }, - { - id: "llama3.1-8b", - name: "Llama 3.1 8B", - reasoning: false, - input: ["text"], - cost: { input: 0.1, output: 0.1, cacheRead: 0.1, cacheWrite: 0.1 }, - }, -] as const; +export const CEREBRAS_BASE_URL = CEREBRAS_MANIFEST_CATALOG.baseUrl; +export const CEREBRAS_MODEL_CATALOG = CEREBRAS_MANIFEST_CATALOG.models; + +export function buildCerebrasCatalogModels(): ModelDefinitionConfig[] { + return buildManifestModelProviderConfig({ + providerId: "cerebras", + catalog: CEREBRAS_MANIFEST_CATALOG, + }).models; +} export function buildCerebrasModelDefinition( model: (typeof CEREBRAS_MODEL_CATALOG)[number], ): ModelDefinitionConfig { - return { - id: model.id, - name: model.name, - api: "openai-completions", - reasoning: model.reasoning, - input: [...model.input], - cost: model.cost, - contextWindow: 128_000, - maxTokens: 8192, - }; + const providerConfig = buildManifestModelProviderConfig({ + providerId: "cerebras", + catalog: { ...CEREBRAS_MANIFEST_CATALOG, models: [model] }, + }); + return providerConfig.models[0]!; } diff --git a/extensions/cerebras/provider-catalog.ts b/extensions/cerebras/provider-catalog.ts index d3c2a09c705..ba670c0998a 100644 --- a/extensions/cerebras/provider-catalog.ts +++ b/extensions/cerebras/provider-catalog.ts @@ -1,14 +1,10 @@ import type { ModelProviderConfig } from "openclaw/plugin-sdk/provider-model-shared"; -import { - buildCerebrasModelDefinition, - CEREBRAS_BASE_URL, - CEREBRAS_MODEL_CATALOG, -} from "./models.js"; +import { buildCerebrasCatalogModels, CEREBRAS_BASE_URL } from "./models.js"; export function buildCerebrasProvider(): ModelProviderConfig { return { baseUrl: CEREBRAS_BASE_URL, api: "openai-completions", - models: CEREBRAS_MODEL_CATALOG.map(buildCerebrasModelDefinition), + models: buildCerebrasCatalogModels(), }; } diff --git a/extensions/mistral/model-definitions.ts b/extensions/mistral/model-definitions.ts index 34012e48171..fa6696e72e7 100644 --- a/extensions/mistral/model-definitions.ts +++ b/extensions/mistral/model-definitions.ts @@ -1,99 +1,38 @@ +import { buildManifestModelProviderConfig } from "openclaw/plugin-sdk/provider-catalog-shared"; import type { ModelDefinitionConfig } from "openclaw/plugin-sdk/provider-model-shared"; +import manifest from "./openclaw.plugin.json" with { type: "json" }; -export const MISTRAL_BASE_URL = "https://api.mistral.ai/v1"; +const MISTRAL_MANIFEST_CATALOG = manifest.modelCatalog.providers.mistral; + +export const MISTRAL_BASE_URL = MISTRAL_MANIFEST_CATALOG.baseUrl; export const MISTRAL_DEFAULT_MODEL_ID = "mistral-large-latest"; export const MISTRAL_DEFAULT_MODEL_REF = `mistral/${MISTRAL_DEFAULT_MODEL_ID}`; -export const MISTRAL_DEFAULT_CONTEXT_WINDOW = 262144; -export const MISTRAL_DEFAULT_MAX_TOKENS = 16384; -export const MISTRAL_DEFAULT_COST = { - input: 0.5, - output: 1.5, - cacheRead: 0, - cacheWrite: 0, -}; -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: 32768, - }, - { - id: "magistral-small", - name: "Magistral Small", - reasoning: true, - input: ["text"], - cost: { input: 0.5, output: 1.5, cacheRead: 0, cacheWrite: 0 }, - contextWindow: 128000, - maxTokens: 40000, - }, - { - 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: 8192, - }, - { - id: "mistral-small-latest", - name: "Mistral Small (latest)", - reasoning: true, - 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: 32768, - }, -] as const satisfies readonly ModelDefinitionConfig[]; +function requireMistralManifestModel(id: string): (typeof MISTRAL_MANIFEST_CATALOG.models)[number] { + const model = MISTRAL_MANIFEST_CATALOG.models.find((entry) => entry.id === id); + if (!model) { + throw new Error(`Missing Mistral modelCatalog row ${id}`); + } + return model; +} + +const MISTRAL_DEFAULT_MANIFEST_MODEL = requireMistralManifestModel(MISTRAL_DEFAULT_MODEL_ID); + +export const MISTRAL_DEFAULT_CONTEXT_WINDOW = MISTRAL_DEFAULT_MANIFEST_MODEL.contextWindow; +export const MISTRAL_DEFAULT_MAX_TOKENS = MISTRAL_DEFAULT_MANIFEST_MODEL.maxTokens; +export const MISTRAL_DEFAULT_COST = MISTRAL_DEFAULT_MANIFEST_MODEL.cost; 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, - } - ); + const model = buildMistralCatalogModels().find((entry) => entry.id === MISTRAL_DEFAULT_MODEL_ID); + if (!model) { + throw new Error(`Missing Mistral provider model ${MISTRAL_DEFAULT_MODEL_ID}`); + } + return model; } export function buildMistralCatalogModels(): ModelDefinitionConfig[] { - return MISTRAL_MODEL_CATALOG.map((model) => - Object.assign({}, model, { input: [...model.input] }), - ); + return buildManifestModelProviderConfig({ + providerId: "mistral", + catalog: MISTRAL_MANIFEST_CATALOG, + }).models; } diff --git a/extensions/mistral/provider-catalog.ts b/extensions/mistral/provider-catalog.ts index 17c595d97ee..056bd5767ed 100644 --- a/extensions/mistral/provider-catalog.ts +++ b/extensions/mistral/provider-catalog.ts @@ -1,10 +1,10 @@ +import { buildManifestModelProviderConfig } from "openclaw/plugin-sdk/provider-catalog-shared"; import type { ModelProviderConfig } from "openclaw/plugin-sdk/provider-model-shared"; -import { buildMistralCatalogModels, MISTRAL_BASE_URL } from "./model-definitions.js"; +import manifest from "./openclaw.plugin.json" with { type: "json" }; export function buildMistralProvider(): ModelProviderConfig { - return { - baseUrl: MISTRAL_BASE_URL, - api: "openai-completions", - models: buildMistralCatalogModels(), - }; + return buildManifestModelProviderConfig({ + providerId: "mistral", + catalog: manifest.modelCatalog.providers.mistral, + }); }