From 305bff60e5215ff01205408705d4958be96dea04 Mon Sep 17 00:00:00 2001 From: = Date: Wed, 3 Dec 2025 23:21:38 +0000 Subject: [PATCH 1/3] feat: add suport for `mistral3` models Mistral released a new series of models with a new `mistral3` architecture. This commit updates the `GgufArchitectureType` so include `mistral3`. This was tested with Ministral-3-3B-Instruct-2512-Q4_K_M.gguf --- src/chatWrappers/utils/resolveChatWrapper.ts | 2 +- src/gguf/types/GgufMetadataTypes.ts | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/chatWrappers/utils/resolveChatWrapper.ts b/src/chatWrappers/utils/resolveChatWrapper.ts index 8cadf9e8..7527aad0 100644 --- a/src/chatWrappers/utils/resolveChatWrapper.ts +++ b/src/chatWrappers/utils/resolveChatWrapper.ts @@ -362,7 +362,7 @@ export function resolveChatWrapper( return createSpecializedChatWrapper(Llama3_1ChatWrapper); else if (includesText(modelNames, ["llama 3", "llama-3", "llama3"])) return createSpecializedChatWrapper(Llama3ChatWrapper); - else if (includesText(modelNames, ["Mistral", "Mistral Large", "Mistral Large Instruct", "Mistral-Large", "Codestral"])) + else if (includesText(modelNames, ["Mistral", "Mistral Large", "Mistral Large Instruct", "Mistral-Large", "Mistral 3", "mistral3", "Ministral", "Codestral"])) return createSpecializedChatWrapper(MistralChatWrapper); else if (includesText(modelNames, ["Gemma", "Gemma 2"])) return createSpecializedChatWrapper(GemmaChatWrapper); diff --git a/src/gguf/types/GgufMetadataTypes.ts b/src/gguf/types/GgufMetadataTypes.ts index ff328737..1a128524 100644 --- a/src/gguf/types/GgufMetadataTypes.ts +++ b/src/gguf/types/GgufMetadataTypes.ts @@ -99,6 +99,7 @@ export const enum GgufArchitectureType { grovemoe = "grovemoe", apertus = "apertus", cogvlm = "cogvlm", + mistral3 = "mistral3", clip = "clip", unknown = "(unknown)" } From 7af234f6d55fb4f51ffc918a35959665a1c37236 Mon Sep 17 00:00:00 2001 From: = Date: Thu, 4 Dec 2025 09:48:44 +0000 Subject: [PATCH 2/3] feat: resolveChatWrapper for mistral3 It will choose the `MistralChatWrapper` if the model architecture is `mistral3` --- src/chatWrappers/utils/resolveChatWrapper.ts | 2 ++ .../utils/resolveChatWrapper.test.ts | 30 +++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/src/chatWrappers/utils/resolveChatWrapper.ts b/src/chatWrappers/utils/resolveChatWrapper.ts index 7527aad0..080d9a73 100644 --- a/src/chatWrappers/utils/resolveChatWrapper.ts +++ b/src/chatWrappers/utils/resolveChatWrapper.ts @@ -454,6 +454,8 @@ export function resolveChatWrapper( return createSpecializedChatWrapper(FalconChatWrapper); else if (arch === "gemma" || arch === "gemma2") return createSpecializedChatWrapper(GemmaChatWrapper); + else if (arch === "mistral3") + return createSpecializedChatWrapper(MistralChatWrapper); } return null; diff --git a/test/standalone/chatWrappers/utils/resolveChatWrapper.test.ts b/test/standalone/chatWrappers/utils/resolveChatWrapper.test.ts index 0523e7e2..80b3f385 100644 --- a/test/standalone/chatWrappers/utils/resolveChatWrapper.test.ts +++ b/test/standalone/chatWrappers/utils/resolveChatWrapper.test.ts @@ -767,4 +767,34 @@ describe("resolveChatWrapper", () => { }); expect(chatWrapper).to.be.instanceof(HarmonyChatWrapper); }); + + test("should resolve to MistralChatWrapper based on mistral3 architecture", () => { + const chatWrapper = resolveChatWrapper({ + fileInfo: { + version: 3, + tensorCount: 0, + metadata: { + general: { + architecture: "mistral3", + // eslint-disable-next-line camelcase + quantization_version: "1" + }, + tokenizer: { + ggml: { + model: "llama", + tokens: [], + // eslint-disable-next-line camelcase + token_type: [] + } + } + } as any, + metadataSize: 0, + architectureMetadata: {} as any, + splicedParts: 1, + totalTensorCount: 0, + totalMetadataSize: 0 + } + }); + expect(chatWrapper).to.be.instanceof(MistralChatWrapper); + }); }); From d9e8fcd2ae721c2e5d5f6db12583cb68d5016627 Mon Sep 17 00:00:00 2001 From: = Date: Sat, 6 Dec 2025 17:41:13 +0000 Subject: [PATCH 3/3] Revert "feat: resolveChatWrapper for mistral3" This reverts commit 7af234f6d55fb4f51ffc918a35959665a1c37236. It's probably best to create a separate `Mistral3ChatWrapper` implementation. For now the existing logic means `mistral3` architecture will use a `JinjaTemplateChatWrapper` --- src/chatWrappers/utils/resolveChatWrapper.ts | 2 -- .../utils/resolveChatWrapper.test.ts | 30 ------------------- 2 files changed, 32 deletions(-) diff --git a/src/chatWrappers/utils/resolveChatWrapper.ts b/src/chatWrappers/utils/resolveChatWrapper.ts index 080d9a73..7527aad0 100644 --- a/src/chatWrappers/utils/resolveChatWrapper.ts +++ b/src/chatWrappers/utils/resolveChatWrapper.ts @@ -454,8 +454,6 @@ export function resolveChatWrapper( return createSpecializedChatWrapper(FalconChatWrapper); else if (arch === "gemma" || arch === "gemma2") return createSpecializedChatWrapper(GemmaChatWrapper); - else if (arch === "mistral3") - return createSpecializedChatWrapper(MistralChatWrapper); } return null; diff --git a/test/standalone/chatWrappers/utils/resolveChatWrapper.test.ts b/test/standalone/chatWrappers/utils/resolveChatWrapper.test.ts index 80b3f385..0523e7e2 100644 --- a/test/standalone/chatWrappers/utils/resolveChatWrapper.test.ts +++ b/test/standalone/chatWrappers/utils/resolveChatWrapper.test.ts @@ -767,34 +767,4 @@ describe("resolveChatWrapper", () => { }); expect(chatWrapper).to.be.instanceof(HarmonyChatWrapper); }); - - test("should resolve to MistralChatWrapper based on mistral3 architecture", () => { - const chatWrapper = resolveChatWrapper({ - fileInfo: { - version: 3, - tensorCount: 0, - metadata: { - general: { - architecture: "mistral3", - // eslint-disable-next-line camelcase - quantization_version: "1" - }, - tokenizer: { - ggml: { - model: "llama", - tokens: [], - // eslint-disable-next-line camelcase - token_type: [] - } - } - } as any, - metadataSize: 0, - architectureMetadata: {} as any, - splicedParts: 1, - totalTensorCount: 0, - totalMetadataSize: 0 - } - }); - expect(chatWrapper).to.be.instanceof(MistralChatWrapper); - }); });