Add Mistral as AI provider

- Add Mistral to KnownProvider type and model generation
- Implement Mistral-specific compat handling in openai-completions:
  - requiresToolResultName: tool results need name field
  - requiresAssistantAfterToolResult: synthetic assistant message between tool/user
  - requiresThinkingAsText: thinking blocks as <thinking> text
  - requiresMistralToolIds: tool IDs must be exactly 9 alphanumeric chars
- Add MISTRAL_API_KEY environment variable support
- Add Mistral tests across all test files
- Update documentation (README, CHANGELOG) for both ai and coding-agent packages
- Remove client IDs from gemini.md, reference upstream source instead

Closes #165
This commit is contained in:
Mario Zechner 2025-12-10 20:36:19 +01:00
parent a248e2547a
commit 99b4b1aca0
31 changed files with 1856 additions and 282 deletions

View file

@ -1989,6 +1989,416 @@ export const MODELS = {
contextWindow: 204800,
maxTokens: 131072,
} satisfies Model<"anthropic-messages">,
"glm-4.6v": {
id: "glm-4.6v",
name: "GLM-4.6V",
api: "anthropic-messages",
provider: "zai",
baseUrl: "https://api.z.ai/api/anthropic",
reasoning: true,
input: ["text", "image"],
cost: {
input: 0.3,
output: 0.9,
cacheRead: 0,
cacheWrite: 0,
},
contextWindow: 128000,
maxTokens: 32768,
} satisfies Model<"anthropic-messages">,
},
mistral: {
"devstral-medium-2507": {
id: "devstral-medium-2507",
name: "Devstral Medium",
api: "openai-completions",
provider: "mistral",
baseUrl: "https://api.mistral.ai/v1",
reasoning: false,
input: ["text"],
cost: {
input: 0.4,
output: 2,
cacheRead: 0,
cacheWrite: 0,
},
contextWindow: 128000,
maxTokens: 128000,
} satisfies Model<"openai-completions">,
"mistral-large-2512": {
id: "mistral-large-2512",
name: "Mistral Large 3",
api: "openai-completions",
provider: "mistral",
baseUrl: "https://api.mistral.ai/v1",
reasoning: false,
input: ["text", "image"],
cost: {
input: 0.5,
output: 1.5,
cacheRead: 0,
cacheWrite: 0,
},
contextWindow: 262144,
maxTokens: 262144,
} satisfies Model<"openai-completions">,
"open-mixtral-8x22b": {
id: "open-mixtral-8x22b",
name: "Mixtral 8x22B",
api: "openai-completions",
provider: "mistral",
baseUrl: "https://api.mistral.ai/v1",
reasoning: false,
input: ["text"],
cost: {
input: 2,
output: 6,
cacheRead: 0,
cacheWrite: 0,
},
contextWindow: 64000,
maxTokens: 64000,
} satisfies Model<"openai-completions">,
"ministral-8b-latest": {
id: "ministral-8b-latest",
name: "Ministral 8B",
api: "openai-completions",
provider: "mistral",
baseUrl: "https://api.mistral.ai/v1",
reasoning: false,
input: ["text"],
cost: {
input: 0.1,
output: 0.1,
cacheRead: 0,
cacheWrite: 0,
},
contextWindow: 128000,
maxTokens: 128000,
} satisfies Model<"openai-completions">,
"pixtral-large-latest": {
id: "pixtral-large-latest",
name: "Pixtral Large",
api: "openai-completions",
provider: "mistral",
baseUrl: "https://api.mistral.ai/v1",
reasoning: false,
input: ["text", "image"],
cost: {
input: 2,
output: 6,
cacheRead: 0,
cacheWrite: 0,
},
contextWindow: 128000,
maxTokens: 128000,
} satisfies Model<"openai-completions">,
"ministral-3b-latest": {
id: "ministral-3b-latest",
name: "Ministral 3B",
api: "openai-completions",
provider: "mistral",
baseUrl: "https://api.mistral.ai/v1",
reasoning: false,
input: ["text"],
cost: {
input: 0.04,
output: 0.04,
cacheRead: 0,
cacheWrite: 0,
},
contextWindow: 128000,
maxTokens: 128000,
} satisfies Model<"openai-completions">,
"pixtral-12b": {
id: "pixtral-12b",
name: "Pixtral 12B",
api: "openai-completions",
provider: "mistral",
baseUrl: "https://api.mistral.ai/v1",
reasoning: false,
input: ["text", "image"],
cost: {
input: 0.15,
output: 0.15,
cacheRead: 0,
cacheWrite: 0,
},
contextWindow: 128000,
maxTokens: 128000,
} satisfies Model<"openai-completions">,
"mistral-medium-2505": {
id: "mistral-medium-2505",
name: "Mistral Medium 3",
api: "openai-completions",
provider: "mistral",
baseUrl: "https://api.mistral.ai/v1",
reasoning: false,
input: ["text", "image"],
cost: {
input: 0.4,
output: 2,
cacheRead: 0,
cacheWrite: 0,
},
contextWindow: 131072,
maxTokens: 131072,
} satisfies Model<"openai-completions">,
"labs-devstral-small-2512": {
id: "labs-devstral-small-2512",
name: "Devstral Small 2",
api: "openai-completions",
provider: "mistral",
baseUrl: "https://api.mistral.ai/v1",
reasoning: false,
input: ["text", "image"],
cost: {
input: 0.1,
output: 0.3,
cacheRead: 0,
cacheWrite: 0,
},
contextWindow: 256000,
maxTokens: 256000,
} satisfies Model<"openai-completions">,
"devstral-medium-latest": {
id: "devstral-medium-latest",
name: "Devstral 2",
api: "openai-completions",
provider: "mistral",
baseUrl: "https://api.mistral.ai/v1",
reasoning: false,
input: ["text"],
cost: {
input: 0.4,
output: 2,
cacheRead: 0,
cacheWrite: 0,
},
contextWindow: 262144,
maxTokens: 262144,
} satisfies Model<"openai-completions">,
"devstral-small-2505": {
id: "devstral-small-2505",
name: "Devstral Small 2505",
api: "openai-completions",
provider: "mistral",
baseUrl: "https://api.mistral.ai/v1",
reasoning: false,
input: ["text"],
cost: {
input: 0.1,
output: 0.3,
cacheRead: 0,
cacheWrite: 0,
},
contextWindow: 128000,
maxTokens: 128000,
} satisfies Model<"openai-completions">,
"mistral-medium-2508": {
id: "mistral-medium-2508",
name: "Mistral Medium 3.1",
api: "openai-completions",
provider: "mistral",
baseUrl: "https://api.mistral.ai/v1",
reasoning: false,
input: ["text", "image"],
cost: {
input: 0.4,
output: 2,
cacheRead: 0,
cacheWrite: 0,
},
contextWindow: 262144,
maxTokens: 262144,
} satisfies Model<"openai-completions">,
"mistral-small-latest": {
id: "mistral-small-latest",
name: "Mistral Small",
api: "openai-completions",
provider: "mistral",
baseUrl: "https://api.mistral.ai/v1",
reasoning: false,
input: ["text", "image"],
cost: {
input: 0.1,
output: 0.3,
cacheRead: 0,
cacheWrite: 0,
},
contextWindow: 128000,
maxTokens: 16384,
} satisfies Model<"openai-completions">,
"magistral-small": {
id: "magistral-small",
name: "Magistral Small",
api: "openai-completions",
provider: "mistral",
baseUrl: "https://api.mistral.ai/v1",
reasoning: true,
input: ["text"],
cost: {
input: 0.5,
output: 1.5,
cacheRead: 0,
cacheWrite: 0,
},
contextWindow: 128000,
maxTokens: 128000,
} satisfies Model<"openai-completions">,
"devstral-small-2507": {
id: "devstral-small-2507",
name: "Devstral Small",
api: "openai-completions",
provider: "mistral",
baseUrl: "https://api.mistral.ai/v1",
reasoning: false,
input: ["text"],
cost: {
input: 0.1,
output: 0.3,
cacheRead: 0,
cacheWrite: 0,
},
contextWindow: 128000,
maxTokens: 128000,
} satisfies Model<"openai-completions">,
"codestral-latest": {
id: "codestral-latest",
name: "Codestral",
api: "openai-completions",
provider: "mistral",
baseUrl: "https://api.mistral.ai/v1",
reasoning: false,
input: ["text"],
cost: {
input: 0.3,
output: 0.9,
cacheRead: 0,
cacheWrite: 0,
},
contextWindow: 256000,
maxTokens: 4096,
} satisfies Model<"openai-completions">,
"open-mixtral-8x7b": {
id: "open-mixtral-8x7b",
name: "Mixtral 8x7B",
api: "openai-completions",
provider: "mistral",
baseUrl: "https://api.mistral.ai/v1",
reasoning: false,
input: ["text"],
cost: {
input: 0.7,
output: 0.7,
cacheRead: 0,
cacheWrite: 0,
},
contextWindow: 32000,
maxTokens: 32000,
} satisfies Model<"openai-completions">,
"mistral-nemo": {
id: "mistral-nemo",
name: "Mistral Nemo",
api: "openai-completions",
provider: "mistral",
baseUrl: "https://api.mistral.ai/v1",
reasoning: false,
input: ["text"],
cost: {
input: 0.15,
output: 0.15,
cacheRead: 0,
cacheWrite: 0,
},
contextWindow: 128000,
maxTokens: 128000,
} satisfies Model<"openai-completions">,
"open-mistral-7b": {
id: "open-mistral-7b",
name: "Mistral 7B",
api: "openai-completions",
provider: "mistral",
baseUrl: "https://api.mistral.ai/v1",
reasoning: false,
input: ["text"],
cost: {
input: 0.25,
output: 0.25,
cacheRead: 0,
cacheWrite: 0,
},
contextWindow: 8000,
maxTokens: 8000,
} satisfies Model<"openai-completions">,
"mistral-large-latest": {
id: "mistral-large-latest",
name: "Mistral Large",
api: "openai-completions",
provider: "mistral",
baseUrl: "https://api.mistral.ai/v1",
reasoning: false,
input: ["text", "image"],
cost: {
input: 0.5,
output: 1.5,
cacheRead: 0,
cacheWrite: 0,
},
contextWindow: 262144,
maxTokens: 262144,
} satisfies Model<"openai-completions">,
"mistral-medium-latest": {
id: "mistral-medium-latest",
name: "Mistral Medium",
api: "openai-completions",
provider: "mistral",
baseUrl: "https://api.mistral.ai/v1",
reasoning: false,
input: ["text", "image"],
cost: {
input: 0.4,
output: 2,
cacheRead: 0,
cacheWrite: 0,
},
contextWindow: 128000,
maxTokens: 16384,
} satisfies Model<"openai-completions">,
"mistral-large-2411": {
id: "mistral-large-2411",
name: "Mistral Large 2.1",
api: "openai-completions",
provider: "mistral",
baseUrl: "https://api.mistral.ai/v1",
reasoning: false,
input: ["text"],
cost: {
input: 2,
output: 6,
cacheRead: 0,
cacheWrite: 0,
},
contextWindow: 131072,
maxTokens: 16384,
} satisfies Model<"openai-completions">,
"magistral-medium-latest": {
id: "magistral-medium-latest",
name: "Magistral Medium",
api: "openai-completions",
provider: "mistral",
baseUrl: "https://api.mistral.ai/v1",
reasoning: true,
input: ["text"],
cost: {
input: 2,
output: 5,
cacheRead: 0,
cacheWrite: 0,
},
contextWindow: 128000,
maxTokens: 16384,
} satisfies Model<"openai-completions">,
},
openrouter: {
"mistralai/devstral-2512:free": {
@ -4448,13 +4858,13 @@ export const MODELS = {
reasoning: false,
input: ["text", "image"],
cost: {
input: 0.136,
output: 0.6799999999999999,
input: 0.15,
output: 0.6,
cacheRead: 0,
cacheWrite: 0,
},
contextWindow: 1048576,
maxTokens: 8192,
maxTokens: 16384,
} satisfies Model<"openai-completions">,
"meta-llama/llama-4-scout": {
id: "meta-llama/llama-4-scout",
@ -5068,23 +5478,6 @@ export const MODELS = {
contextWindow: 200000,
maxTokens: 8192,
} satisfies Model<"openai-completions">,
"mistralai/ministral-3b": {
id: "mistralai/ministral-3b",
name: "Mistral: Ministral 3B",
api: "openai-completions",
provider: "openrouter",
baseUrl: "https://openrouter.ai/api/v1",
reasoning: false,
input: ["text"],
cost: {
input: 0.04,
output: 0.04,
cacheRead: 0,
cacheWrite: 0,
},
contextWindow: 131072,
maxTokens: 4096,
} satisfies Model<"openai-completions">,
"mistralai/ministral-8b": {
id: "mistralai/ministral-8b",
name: "Mistral: Ministral 8B",
@ -5102,6 +5495,23 @@ export const MODELS = {
contextWindow: 131072,
maxTokens: 4096,
} satisfies Model<"openai-completions">,
"mistralai/ministral-3b": {
id: "mistralai/ministral-3b",
name: "Mistral: Ministral 3B",
api: "openai-completions",
provider: "openrouter",
baseUrl: "https://openrouter.ai/api/v1",
reasoning: false,
input: ["text"],
cost: {
input: 0.04,
output: 0.04,
cacheRead: 0,
cacheWrite: 0,
},
contextWindow: 131072,
maxTokens: 4096,
} satisfies Model<"openai-completions">,
"nvidia/llama-3.1-nemotron-70b-instruct": {
id: "nvidia/llama-3.1-nemotron-70b-instruct",
name: "NVIDIA: Llama 3.1 Nemotron 70B Instruct",
@ -5272,6 +5682,23 @@ export const MODELS = {
contextWindow: 128000,
maxTokens: 16384,
} satisfies Model<"openai-completions">,
"meta-llama/llama-3.1-8b-instruct": {
id: "meta-llama/llama-3.1-8b-instruct",
name: "Meta: Llama 3.1 8B Instruct",
api: "openai-completions",
provider: "openrouter",
baseUrl: "https://openrouter.ai/api/v1",
reasoning: false,
input: ["text"],
cost: {
input: 0.02,
output: 0.03,
cacheRead: 0,
cacheWrite: 0,
},
contextWindow: 131072,
maxTokens: 16384,
} satisfies Model<"openai-completions">,
"meta-llama/llama-3.1-405b-instruct": {
id: "meta-llama/llama-3.1-405b-instruct",
name: "Meta: Llama 3.1 405B Instruct",
@ -5306,23 +5733,6 @@ export const MODELS = {
contextWindow: 131072,
maxTokens: 4096,
} satisfies Model<"openai-completions">,
"meta-llama/llama-3.1-8b-instruct": {
id: "meta-llama/llama-3.1-8b-instruct",
name: "Meta: Llama 3.1 8B Instruct",
api: "openai-completions",
provider: "openrouter",
baseUrl: "https://openrouter.ai/api/v1",
reasoning: false,
input: ["text"],
cost: {
input: 0.02,
output: 0.03,
cacheRead: 0,
cacheWrite: 0,
},
contextWindow: 131072,
maxTokens: 16384,
} satisfies Model<"openai-completions">,
"mistralai/mistral-nemo": {
id: "mistralai/mistral-nemo",
name: "Mistral: Mistral Nemo",
@ -5459,6 +5869,23 @@ export const MODELS = {
contextWindow: 128000,
maxTokens: 4096,
} satisfies Model<"openai-completions">,
"openai/gpt-4o-2024-05-13": {
id: "openai/gpt-4o-2024-05-13",
name: "OpenAI: GPT-4o (2024-05-13)",
api: "openai-completions",
provider: "openrouter",
baseUrl: "https://openrouter.ai/api/v1",
reasoning: false,
input: ["text", "image"],
cost: {
input: 5,
output: 15,
cacheRead: 0,
cacheWrite: 0,
},
contextWindow: 128000,
maxTokens: 4096,
} satisfies Model<"openai-completions">,
"openai/gpt-4o": {
id: "openai/gpt-4o",
name: "OpenAI: GPT-4o",
@ -5493,22 +5920,22 @@ export const MODELS = {
contextWindow: 128000,
maxTokens: 64000,
} satisfies Model<"openai-completions">,
"openai/gpt-4o-2024-05-13": {
id: "openai/gpt-4o-2024-05-13",
name: "OpenAI: GPT-4o (2024-05-13)",
"meta-llama/llama-3-70b-instruct": {
id: "meta-llama/llama-3-70b-instruct",
name: "Meta: Llama 3 70B Instruct",
api: "openai-completions",
provider: "openrouter",
baseUrl: "https://openrouter.ai/api/v1",
reasoning: false,
input: ["text", "image"],
input: ["text"],
cost: {
input: 5,
output: 15,
input: 0.3,
output: 0.39999999999999997,
cacheRead: 0,
cacheWrite: 0,
},
contextWindow: 128000,
maxTokens: 4096,
contextWindow: 8192,
maxTokens: 16384,
} satisfies Model<"openai-completions">,
"meta-llama/llama-3-8b-instruct": {
id: "meta-llama/llama-3-8b-instruct",
@ -5527,23 +5954,6 @@ export const MODELS = {
contextWindow: 8192,
maxTokens: 16384,
} satisfies Model<"openai-completions">,
"meta-llama/llama-3-70b-instruct": {
id: "meta-llama/llama-3-70b-instruct",
name: "Meta: Llama 3 70B Instruct",
api: "openai-completions",
provider: "openrouter",
baseUrl: "https://openrouter.ai/api/v1",
reasoning: false,
input: ["text"],
cost: {
input: 0.3,
output: 0.39999999999999997,
cacheRead: 0,
cacheWrite: 0,
},
contextWindow: 8192,
maxTokens: 16384,
} satisfies Model<"openai-completions">,
"mistralai/mixtral-8x22b-instruct": {
id: "mistralai/mixtral-8x22b-instruct",
name: "Mistral: Mixtral 8x22B Instruct",
@ -5629,23 +6039,6 @@ export const MODELS = {
contextWindow: 128000,
maxTokens: 4096,
} satisfies Model<"openai-completions">,
"openai/gpt-4-turbo-preview": {
id: "openai/gpt-4-turbo-preview",
name: "OpenAI: GPT-4 Turbo Preview",
api: "openai-completions",
provider: "openrouter",
baseUrl: "https://openrouter.ai/api/v1",
reasoning: false,
input: ["text"],
cost: {
input: 10,
output: 30,
cacheRead: 0,
cacheWrite: 0,
},
contextWindow: 128000,
maxTokens: 4096,
} satisfies Model<"openai-completions">,
"openai/gpt-3.5-turbo-0613": {
id: "openai/gpt-3.5-turbo-0613",
name: "OpenAI: GPT-3.5 Turbo (older v0613)",
@ -5663,6 +6056,23 @@ export const MODELS = {
contextWindow: 4095,
maxTokens: 4096,
} satisfies Model<"openai-completions">,
"openai/gpt-4-turbo-preview": {
id: "openai/gpt-4-turbo-preview",
name: "OpenAI: GPT-4 Turbo Preview",
api: "openai-completions",
provider: "openrouter",
baseUrl: "https://openrouter.ai/api/v1",
reasoning: false,
input: ["text"],
cost: {
input: 10,
output: 30,
cacheRead: 0,
cacheWrite: 0,
},
contextWindow: 128000,
maxTokens: 4096,
} satisfies Model<"openai-completions">,
"mistralai/mistral-tiny": {
id: "mistralai/mistral-tiny",
name: "Mistral Tiny",
@ -5731,6 +6141,23 @@ export const MODELS = {
contextWindow: 16385,
maxTokens: 4096,
} satisfies Model<"openai-completions">,
"openai/gpt-4-0314": {
id: "openai/gpt-4-0314",
name: "OpenAI: GPT-4 (older v0314)",
api: "openai-completions",
provider: "openrouter",
baseUrl: "https://openrouter.ai/api/v1",
reasoning: false,
input: ["text"],
cost: {
input: 30,
output: 60,
cacheRead: 0,
cacheWrite: 0,
},
contextWindow: 8191,
maxTokens: 4096,
} satisfies Model<"openai-completions">,
"openai/gpt-4": {
id: "openai/gpt-4",
name: "OpenAI: GPT-4",
@ -5765,23 +6192,6 @@ export const MODELS = {
contextWindow: 16385,
maxTokens: 4096,
} satisfies Model<"openai-completions">,
"openai/gpt-4-0314": {
id: "openai/gpt-4-0314",
name: "OpenAI: GPT-4 (older v0314)",
api: "openai-completions",
provider: "openrouter",
baseUrl: "https://openrouter.ai/api/v1",
reasoning: false,
input: ["text"],
cost: {
input: 30,
output: 60,
cacheRead: 0,
cacheWrite: 0,
},
contextWindow: 8191,
maxTokens: 4096,
} satisfies Model<"openai-completions">,
"openrouter/auto": {
id: "openrouter/auto",
name: "OpenRouter: Auto Router",