@warlock.js/ai-mistral 4.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,13 @@
1
+ # Changelog — @warlock.js/ai-mistral
2
+
3
+ All notable changes to `@warlock.js/ai-mistral` are documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). `@warlock.js/*` packages are released in lockstep — every package shares the same version number, so a version below may list only the changes that affected this package.
6
+
7
+ ## 4.6.0
8
+
9
+ ### Added
10
+
11
+ - **First release.** `MistralSDK` — a thin wrapper over `@warlock.js/ai-openai` that points one internal `OpenAISDK` at Mistral's OpenAI-compatible endpoint (`https://api.mistral.ai/v1`) with `provider: "mistral"`, delegating transport, streaming, tool calls, structured output, error wrapping, and token accounting to the battle-tested adapter. Exposes `.model()`, `.embedder()` (`mistral-embed`), and `.count()`.
12
+ - **Mistral-aware capability inference** — `vision` is auto-set for the `pixtral` family and recent multimodal generations (`mistral-large`, `mistral-medium`, `ministral-3`); `reasoning` for the `magistral` family and the hybrid `mistral-small` generation. An explicit `vision` / `reasoning` on `.model()` always wins. Exported as `inferVisionCapability` / `inferReasoningCapability`, with the `-latest` aliases grouped under `MISTRAL_MODELS`.
13
+ - **Default pricing registry** (`MISTRAL_DEFAULT_PRICING`, USD per 1,000,000 tokens) merged under any caller-supplied `pricing` so cost truth works out of the box; per-model > SDK-level > default > `undefined`. No `image()` — Mistral has no OpenAI-compatible image endpoint.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) Hassan Zohdy
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,127 @@
1
+ # @warlock.js/ai-mistral
2
+
3
+ Mistral AI adapter for [`@warlock.js/ai`](../ai). Mistral exposes an **OpenAI-compatible** Chat Completions + Embeddings API, so this package is a **thin wrapper** over [`@warlock.js/ai-openai`](../ai-openai): `MistralSDK` builds one internal `OpenAISDK` pointed at Mistral's `baseURL` with `provider: "mistral"` and delegates every call to it. It does not re-implement the wire protocol, streaming, tool-call accumulation, structured output, error wrapping, or token accounting.
4
+
5
+ ```bash
6
+ npm install @warlock.js/ai @warlock.js/ai-openai @warlock.js/ai-mistral @warlock.js/seal openai
7
+ ```
8
+
9
+ > `@warlock.js/seal` is the recommended Standard Schema library for tool inputs and structured output. Any Standard Schema V1 library works (Zod, Valibot, …).
10
+
11
+ ## Quick start
12
+
13
+ ```ts
14
+ import { MistralSDK } from "@warlock.js/ai-mistral";
15
+ import { ai } from "@warlock.js/ai";
16
+
17
+ const mistral = new MistralSDK({ apiKey: process.env.MISTRAL_API_KEY! });
18
+
19
+ const myAgent = ai.agent({
20
+ model: mistral.model({ name: "mistral-large-latest" }),
21
+ });
22
+
23
+ const result = await myAgent.execute("Hello!");
24
+ console.log(result.text);
25
+ ```
26
+
27
+ Construct one SDK per account and reuse it everywhere — the single underlying `OpenAI` client (connection pool, auth, rate-limit state) is shared by every model and embedder it produces.
28
+
29
+ ## API surface
30
+
31
+ ```ts
32
+ new MistralSDK(config: MistralSDKConfig) // = OpenAI ClientOptions + provider/pricing defaults
33
+ .model(config: MistralModelConfig) // → ModelContract
34
+ .embedder(config: EmbedderConfig) // → EmbedderContract
35
+ .count(text, model?) // approximate token count
36
+
37
+ MistralModelConfig {
38
+ name: string; // e.g. "mistral-large-latest", "magistral-medium-latest"
39
+ temperature?: number;
40
+ maxTokens?: number;
41
+ vision?: boolean; // override auto-inference (pixtral family, recent generations)
42
+ reasoning?: boolean; // override auto-inference (magistral family, hybrid mistral-small)
43
+ structuredOutput?: boolean;
44
+ responseFormat?: "json_schema" | "json_object" | "text";
45
+ pdf?: boolean; // opt into PDF document input (default false)
46
+ audio?: boolean; // opt into audio input (default false)
47
+ // ...neutral ModelConfig fields pass through
48
+ }
49
+ ```
50
+
51
+ ## Base URL & model families
52
+
53
+ `baseURL` defaults to `https://api.mistral.ai/v1` (Mistral's OpenAI-compatible endpoint serving `/chat/completions` and `/embeddings`). Override it only to reach a Mistral-compatible gateway or proxy. `provider` defaults to `"mistral"` and flows through to `ModelContract.provider`, `AgentReport.model.provider`, and logs. Every other upstream OpenAI `ClientOptions` field (`timeout`, `maxRetries`, `defaultHeaders`, `fetch`, …) is forwarded verbatim.
54
+
55
+ The headline `-latest` aliases are exported as `MISTRAL_MODELS`, grouped by role:
56
+
57
+ | Family | Aliases | Notes |
58
+ | --- | --- | --- |
59
+ | `chat` | `mistral-large-latest`, `mistral-medium-latest`, `mistral-small-latest` | General-purpose multimodal flagship / mid / small |
60
+ | `vision` | `pixtral-large-latest`, `pixtral-12b` | Dedicated multimodal (image input) |
61
+ | `reasoning` | `magistral-medium-latest`, `magistral-small-latest` | Chain-of-thought reasoning |
62
+ | `embedding` | `mistral-embed` | Via the OpenAI-compatible `/v1/embeddings` |
63
+
64
+ `mistral.model()` accepts any id string, so version-pinned ids (`mistral-large-2512`, `magistral-medium-2509`) work just as well — capability inference keys off the family fragment, not the alias list.
65
+
66
+ ## Capabilities
67
+
68
+ The wrapper injects **Mistral-aware** capability inference before delegating to the OpenAI adapter, because the OpenAI prefix lists (`gpt-4o`, `o3`, …) never match Mistral names. An explicit value always wins over inference.
69
+
70
+ | Capability | Default |
71
+ | --- | --- |
72
+ | `vision` | Inferred from the model name — `true` for the `pixtral` family and the recent multimodal generations (`mistral-large`, `mistral-medium`, `ministral-3`); `false` otherwise. |
73
+ | `reasoning` | Inferred from the model name — `true` for the `magistral` family and the hybrid `mistral-small` generation; `false` otherwise. Drives whether `reasoning.effort` maps to `reasoning_effort` on the wire. |
74
+ | `structuredOutput` | `true`, unless `responseFormat` is forced to `"json_object"` / `"text"`. |
75
+
76
+ ```ts
77
+ mistral.model({ name: "pixtral-large-latest" }); // vision auto-true
78
+ mistral.model({ name: "magistral-medium-latest" }); // reasoning auto-true
79
+ mistral.model({ name: "some-fine-tune", vision: true }); // explicit override
80
+ ```
81
+
82
+ ## Embeddings
83
+
84
+ `mistral-embed` is served through the OpenAI-compatible `/v1/embeddings`, so the embedder delegates straight to the wrapped OpenAI embedder:
85
+
86
+ ```ts
87
+ const embedder = mistral.embedder({ name: "mistral-embed" });
88
+
89
+ const { vector, dimensions, usage } = await embedder.embed("Hello world");
90
+ const { vectors } = await embedder.embedMany(["doc 1", "doc 2"]);
91
+ ```
92
+
93
+ ## Pricing
94
+
95
+ The adapter ships a conservative default registry (`MISTRAL_DEFAULT_PRICING`, USD per 1,000,000 tokens) so cost truth works out of the box. Supply your own `pricing` to win per model id:
96
+
97
+ ```ts
98
+ const mistral = new MistralSDK({
99
+ apiKey: process.env.MISTRAL_API_KEY!,
100
+ pricing: {
101
+ "mistral-large-latest": { input: 2, output: 6 },
102
+ "magistral-medium-latest": { input: 2, output: 5 },
103
+ },
104
+ });
105
+ ```
106
+
107
+ Resolution at `model()` time: per-model `pricing` > SDK-level `pricing` > `MISTRAL_DEFAULT_PRICING` > `undefined`. The defaults are list-price approximations — pass explicit rates for billing-grade numbers.
108
+
109
+ ## No image generation
110
+
111
+ Mistral has no OpenAI-compatible image endpoint, so `MistralSDK` intentionally does **not** expose `image()`. The structural absence of the method is the capability guard — `ai.mistral.image(...)` is a compile-time error rather than a runtime failure.
112
+
113
+ ## Setup skill
114
+
115
+ For agent wiring, capability inference, and pricing detail, see the bundled setup skill: [`skills/setup-mistral/SKILL.md`](./skills/setup-mistral/SKILL.md).
116
+
117
+ ## Tests
118
+
119
+ ```bash
120
+ npm test
121
+ ```
122
+
123
+ Covers baseURL / provider wiring, Mistral-aware vision & reasoning inference, pricing resolution, and embedder / count delegation.
124
+
125
+ ## License
126
+
127
+ MIT
package/cjs/index.cjs ADDED
@@ -0,0 +1,277 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
+ let _warlock_js_ai_openai = require("@warlock.js/ai-openai");
3
+
4
+ //#region ../@warlock.js/ai-mistral/src/known-models.ts
5
+ /**
6
+ * Model-name fragments identifying Mistral families that accept image
7
+ * input (vision / multimodal).
8
+ *
9
+ * - `pixtral` — Mistral's dedicated multimodal family
10
+ * (`pixtral-large-latest`, `pixtral-12b`); documents, charts, and
11
+ * natural images.
12
+ * - `mistral-large` / `mistral-medium` — the recent frontier generations
13
+ * (Large 3, Medium 3.5) are natively multimodal.
14
+ * - `ministral-3` — the current small open-weight line ships with
15
+ * best-in-class text + vision.
16
+ *
17
+ * Matched as a **substring** (not a strict prefix) so the date / version
18
+ * suffixes Mistral appends (`pixtral-large-2411`, `mistral-large-2512`)
19
+ * and the `-latest` aliases are all covered without enumerating every
20
+ * release tag. Override per-model via
21
+ * `mistral.model({ name, vision: true | false })` — explicit config
22
+ * always wins over inference.
23
+ *
24
+ * Maintenance: append a fragment when Mistral ships a multimodal family
25
+ * that doesn't already match.
26
+ */
27
+ const VISION_CAPABLE_SUBSTRINGS = [
28
+ "pixtral",
29
+ "mistral-large",
30
+ "mistral-medium",
31
+ "ministral-3"
32
+ ];
33
+ /**
34
+ * Model-name fragments identifying Mistral families that perform
35
+ * explicit chain-of-thought reasoning.
36
+ *
37
+ * - `magistral` — Mistral's dedicated reasoning family
38
+ * (`magistral-medium-latest`, `magistral-small-latest`); emits
39
+ * tokenized thinking chunks.
40
+ * - `mistral-small-4` / `mistral-small` — the current Small generation
41
+ * is a hybrid model that unifies instruct + reasoning + coding.
42
+ *
43
+ * Matched as a **substring** so version-tagged ids
44
+ * (`magistral-medium-2509`, `mistral-small-2603`) and `-latest` aliases
45
+ * are covered. Override per-model via
46
+ * `mistral.model({ name, reasoning: true | false })` — explicit config
47
+ * always wins over inference.
48
+ *
49
+ * Maintenance: append a fragment when Mistral ships a reasoning family
50
+ * that doesn't already match.
51
+ */
52
+ const REASONING_CAPABLE_SUBSTRINGS = ["magistral", "mistral-small"];
53
+ /**
54
+ * Infer whether a Mistral model id accepts image input (vision) based on
55
+ * the known multimodal-family fragments. Unknown ids default to `false`
56
+ * so passing an image attachment to a text-only model surfaces a clear,
57
+ * agent-side capability error instead of an opaque Mistral 400.
58
+ *
59
+ * @example
60
+ * inferVisionCapability("pixtral-large-latest"); // → true
61
+ * inferVisionCapability("mistral-large-2512"); // → true
62
+ * inferVisionCapability("magistral-medium-latest");// → false
63
+ * inferVisionCapability("mistral-embed"); // → false
64
+ */
65
+ function inferVisionCapability(modelName) {
66
+ const normalized = modelName.toLowerCase();
67
+ return VISION_CAPABLE_SUBSTRINGS.some((fragment) => normalized.includes(fragment));
68
+ }
69
+ /**
70
+ * Infer whether a Mistral model id is a reasoning model (the `magistral`
71
+ * family plus the hybrid `mistral-small` generation) based on the known
72
+ * fragments. Unknown ids default to `false` so the adapter never forwards
73
+ * an unsupported `reasoning_effort` param to a non-reasoning model.
74
+ *
75
+ * @example
76
+ * inferReasoningCapability("magistral-medium-latest"); // → true
77
+ * inferReasoningCapability("mistral-small-2603"); // → true
78
+ * inferReasoningCapability("mistral-large-latest"); // → false
79
+ * inferReasoningCapability("pixtral-12b"); // → false
80
+ */
81
+ function inferReasoningCapability(modelName) {
82
+ const normalized = modelName.toLowerCase();
83
+ return REASONING_CAPABLE_SUBSTRINGS.some((fragment) => normalized.includes(fragment));
84
+ }
85
+ /**
86
+ * Stable `-latest` alias ids for the headline Mistral chat / embeddings
87
+ * models, grouped by role. Convenience constants only — `mistral.model()`
88
+ * accepts any id string, so a version-pinned id
89
+ * (`mistral-large-2512`, `magistral-medium-2509`) works just as well.
90
+ * Capability inference keys off the family fragment, not this list, so a
91
+ * newer alias is recognized the moment its name matches a fragment in
92
+ * {@link inferVisionCapability} / {@link inferReasoningCapability}.
93
+ */
94
+ const MISTRAL_MODELS = {
95
+ /** General-purpose multimodal flagship / mid / small chat aliases. */
96
+ chat: [
97
+ "mistral-large-latest",
98
+ "mistral-medium-latest",
99
+ "mistral-small-latest"
100
+ ],
101
+ /** Dedicated multimodal (vision) aliases — the `pixtral` family. */
102
+ vision: ["pixtral-large-latest", "pixtral-12b"],
103
+ /** Dedicated reasoning aliases — the `magistral` family. */
104
+ reasoning: ["magistral-medium-latest", "magistral-small-latest"],
105
+ /** Embeddings model reachable via the OpenAI-compatible `/v1/embeddings`. */
106
+ embedding: ["mistral-embed"]
107
+ };
108
+ /**
109
+ * Conservative default USD pricing registry (per 1,000,000 tokens),
110
+ * keyed by stable `-latest` alias, surfaced onto every model unless the
111
+ * caller overrides it via SDK-level or per-model `pricing`.
112
+ *
113
+ * These are sane published-list approximations for budgeting / cost-truth
114
+ * out of the box — Mistral revises rates and ships new generations, so
115
+ * pass an explicit `pricing` registry to `new MistralSDK({ pricing })`
116
+ * for billing-grade numbers. Resolution at `model()` time always lets a
117
+ * caller-supplied rate win: per-model `pricing` > SDK `pricing` > these
118
+ * defaults > `undefined`.
119
+ */
120
+ const MISTRAL_DEFAULT_PRICING = {
121
+ "mistral-large-latest": {
122
+ input: 2,
123
+ output: 6
124
+ },
125
+ "mistral-medium-latest": {
126
+ input: .4,
127
+ output: 2
128
+ },
129
+ "mistral-small-latest": {
130
+ input: .1,
131
+ output: .3
132
+ },
133
+ "pixtral-large-latest": {
134
+ input: 2,
135
+ output: 6
136
+ },
137
+ "pixtral-12b": {
138
+ input: .15,
139
+ output: .15
140
+ },
141
+ "magistral-medium-latest": {
142
+ input: 2,
143
+ output: 5
144
+ },
145
+ "magistral-small-latest": {
146
+ input: .5,
147
+ output: 1.5
148
+ },
149
+ "mistral-embed": {
150
+ input: .1,
151
+ output: 0
152
+ }
153
+ };
154
+
155
+ //#endregion
156
+ //#region ../@warlock.js/ai-mistral/src/sdk.ts
157
+ /** Default OpenAI-compatible base URL for the Mistral API. */
158
+ const MISTRAL_BASE_URL = "https://api.mistral.ai/v1";
159
+ /** Default provider label stamped onto every model this SDK produces. */
160
+ const MISTRAL_PROVIDER = "mistral";
161
+ /**
162
+ * Mistral-backed implementation of `SDKAdapterContract`.
163
+ *
164
+ * **Role.** The package entry point for Mistral AI chat + embeddings.
165
+ * Mistral exposes an **OpenAI-compatible** API (`/v1/chat/completions`,
166
+ * `/v1/embeddings`), so `MistralSDK` is a *thin wrapper* over the
167
+ * battle-tested {@link OpenAISDK} — it does NOT re-implement the wire
168
+ * protocol, streaming loop, tool-call accumulation, structured-output
169
+ * mapping, error wrapping, or token accounting. It constructs one
170
+ * internal `OpenAISDK` pointed at Mistral's `baseURL` with
171
+ * `provider: "mistral"`, and delegates `model()` / `embedder()` /
172
+ * `count()` straight to it.
173
+ *
174
+ * **What this wrapper adds on top of the OpenAI adapter:**
175
+ * - **Defaults.** Injects Mistral's `baseURL` + `provider` label and a
176
+ * default {@link MISTRAL_DEFAULT_PRICING} registry so cost truth works
177
+ * out of the box. All are overridable via config.
178
+ * - **Provider-correct capability inference.** Mistral's model names
179
+ * aren't OpenAI names, so the OpenAI prefix lists never match. Before
180
+ * delegating `model()`, this wrapper infers `vision` (the `pixtral`
181
+ * family + recent multimodal generations) and `reasoning` (the
182
+ * `magistral` family + hybrid `mistral-small`) from *this provider's*
183
+ * fragment lists and passes them as explicit overrides — which the
184
+ * inner `OpenAISDK` honors verbatim. A caller-supplied explicit
185
+ * `vision` / `reasoning` still wins.
186
+ *
187
+ * Construct one SDK per account and reuse it everywhere; the single
188
+ * underlying `OpenAI` client (connection pool, auth, rate-limit state)
189
+ * is shared by every model / embedder produced here.
190
+ *
191
+ * **Note — no image generation.** Mistral has no OpenAI-compatible image
192
+ * endpoint, so `image()` is intentionally NOT exposed. The structural
193
+ * absence of the method IS the capability guard (see
194
+ * `SDKAdapterContract.image`): `ai.mistral.image(...)` is a compile-time
195
+ * error rather than a runtime failure.
196
+ *
197
+ * @example
198
+ * const mistral = new MistralSDK({ apiKey: process.env.MISTRAL_API_KEY! });
199
+ * const model = mistral.model({ name: "mistral-large-latest", temperature: 0.7 });
200
+ * const embedder = mistral.embedder({ name: "mistral-embed" });
201
+ *
202
+ * @example
203
+ * // Compose into an `ai.mistral` namespace for ergonomic agent wiring.
204
+ * const ai = { agent, tool, systemPrompt, mistral: new MistralSDK({ apiKey }) };
205
+ * const reasoner = ai.agent({ model: ai.mistral.model({ name: "magistral-medium-latest" }) });
206
+ */
207
+ var MistralSDK = class {
208
+ constructor(config) {
209
+ const { provider, baseURL, pricing, ...clientOptions } = config;
210
+ const mergedPricing = {
211
+ ...MISTRAL_DEFAULT_PRICING,
212
+ ...pricing
213
+ };
214
+ this.openai = new _warlock_js_ai_openai.OpenAISDK({
215
+ ...clientOptions,
216
+ baseURL: baseURL ?? MISTRAL_BASE_URL,
217
+ provider: provider ?? MISTRAL_PROVIDER,
218
+ pricing: mergedPricing
219
+ });
220
+ }
221
+ /**
222
+ * Build a `ModelContract` for a Mistral chat model.
223
+ *
224
+ * Delegates to the inner `OpenAISDK.model()` but first injects
225
+ * **Mistral-aware capability inference**: when the caller omits
226
+ * `vision` / `reasoning`, they're inferred from this provider's family
227
+ * fragments (`pixtral` → vision, `magistral` / `mistral-small` →
228
+ * reasoning, see `known-models.ts`) and passed down as explicit
229
+ * overrides. Without this step the wrapped OpenAI adapter would check
230
+ * Mistral ids against OpenAI prefixes (`gpt-4o`, `o3`, …) and wrongly
231
+ * report every Mistral model as non-vision / non-reasoning.
232
+ *
233
+ * A caller-supplied explicit `vision` / `reasoning` is preserved as-is
234
+ * (explicit config always wins over inference). Pricing resolution is
235
+ * handled downstream by `OpenAISDK` against the merged registry:
236
+ * per-model `pricing` > SDK registry (caller + Mistral defaults) >
237
+ * `undefined`.
238
+ */
239
+ model(config) {
240
+ const resolvedConfig = {
241
+ ...config,
242
+ vision: config.vision ?? inferVisionCapability(config.name),
243
+ reasoning: config.reasoning ?? inferReasoningCapability(config.name)
244
+ };
245
+ return this.openai.model(resolvedConfig);
246
+ }
247
+ /**
248
+ * Rough offline token-count estimate. Delegates to the wrapped
249
+ * `OpenAISDK.count()` (the shared character-heuristic from the core
250
+ * package) — good for budgeting / quota guards, not billing. The
251
+ * optional model id is forwarded but currently ignored.
252
+ */
253
+ async count(text, model) {
254
+ return this.openai.count(text, model);
255
+ }
256
+ /**
257
+ * Build an `EmbedderContract` bound to this SDK's client. Mistral
258
+ * serves embeddings (`mistral-embed`) through the OpenAI-compatible
259
+ * `/v1/embeddings` endpoint, so this delegates straight to
260
+ * `OpenAISDK.embedder()`.
261
+ *
262
+ * @example
263
+ * const embedder = mistral.embedder({ name: "mistral-embed" });
264
+ * const { vector } = await embedder.embed("Hello world");
265
+ */
266
+ embedder(config) {
267
+ return this.openai.embedder(config);
268
+ }
269
+ };
270
+
271
+ //#endregion
272
+ exports.MISTRAL_DEFAULT_PRICING = MISTRAL_DEFAULT_PRICING;
273
+ exports.MISTRAL_MODELS = MISTRAL_MODELS;
274
+ exports.MistralSDK = MistralSDK;
275
+ exports.inferReasoningCapability = inferReasoningCapability;
276
+ exports.inferVisionCapability = inferVisionCapability;
277
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","names":["OpenAISDK"],"sources":["../../../../../../@warlock.js/ai-mistral/src/known-models.ts","../../../../../../@warlock.js/ai-mistral/src/sdk.ts"],"sourcesContent":["import type { ModelPricing } from \"@warlock.js/ai\";\n\n/**\n * Model-name fragments identifying Mistral families that accept image\n * input (vision / multimodal).\n *\n * - `pixtral` — Mistral's dedicated multimodal family\n * (`pixtral-large-latest`, `pixtral-12b`); documents, charts, and\n * natural images.\n * - `mistral-large` / `mistral-medium` — the recent frontier generations\n * (Large 3, Medium 3.5) are natively multimodal.\n * - `ministral-3` — the current small open-weight line ships with\n * best-in-class text + vision.\n *\n * Matched as a **substring** (not a strict prefix) so the date / version\n * suffixes Mistral appends (`pixtral-large-2411`, `mistral-large-2512`)\n * and the `-latest` aliases are all covered without enumerating every\n * release tag. Override per-model via\n * `mistral.model({ name, vision: true | false })` — explicit config\n * always wins over inference.\n *\n * Maintenance: append a fragment when Mistral ships a multimodal family\n * that doesn't already match.\n */\nconst VISION_CAPABLE_SUBSTRINGS = [\n \"pixtral\",\n \"mistral-large\",\n \"mistral-medium\",\n \"ministral-3\",\n] as const;\n\n/**\n * Model-name fragments identifying Mistral families that perform\n * explicit chain-of-thought reasoning.\n *\n * - `magistral` — Mistral's dedicated reasoning family\n * (`magistral-medium-latest`, `magistral-small-latest`); emits\n * tokenized thinking chunks.\n * - `mistral-small-4` / `mistral-small` — the current Small generation\n * is a hybrid model that unifies instruct + reasoning + coding.\n *\n * Matched as a **substring** so version-tagged ids\n * (`magistral-medium-2509`, `mistral-small-2603`) and `-latest` aliases\n * are covered. Override per-model via\n * `mistral.model({ name, reasoning: true | false })` — explicit config\n * always wins over inference.\n *\n * Maintenance: append a fragment when Mistral ships a reasoning family\n * that doesn't already match.\n */\nconst REASONING_CAPABLE_SUBSTRINGS = [\"magistral\", \"mistral-small\"] as const;\n\n/**\n * Infer whether a Mistral model id accepts image input (vision) based on\n * the known multimodal-family fragments. Unknown ids default to `false`\n * so passing an image attachment to a text-only model surfaces a clear,\n * agent-side capability error instead of an opaque Mistral 400.\n *\n * @example\n * inferVisionCapability(\"pixtral-large-latest\"); // → true\n * inferVisionCapability(\"mistral-large-2512\"); // → true\n * inferVisionCapability(\"magistral-medium-latest\");// → false\n * inferVisionCapability(\"mistral-embed\"); // → false\n */\nexport function inferVisionCapability(modelName: string): boolean {\n const normalized = modelName.toLowerCase();\n\n return VISION_CAPABLE_SUBSTRINGS.some((fragment) => normalized.includes(fragment));\n}\n\n/**\n * Infer whether a Mistral model id is a reasoning model (the `magistral`\n * family plus the hybrid `mistral-small` generation) based on the known\n * fragments. Unknown ids default to `false` so the adapter never forwards\n * an unsupported `reasoning_effort` param to a non-reasoning model.\n *\n * @example\n * inferReasoningCapability(\"magistral-medium-latest\"); // → true\n * inferReasoningCapability(\"mistral-small-2603\"); // → true\n * inferReasoningCapability(\"mistral-large-latest\"); // → false\n * inferReasoningCapability(\"pixtral-12b\"); // → false\n */\nexport function inferReasoningCapability(modelName: string): boolean {\n const normalized = modelName.toLowerCase();\n\n return REASONING_CAPABLE_SUBSTRINGS.some((fragment) => normalized.includes(fragment));\n}\n\n/**\n * Stable `-latest` alias ids for the headline Mistral chat / embeddings\n * models, grouped by role. Convenience constants only — `mistral.model()`\n * accepts any id string, so a version-pinned id\n * (`mistral-large-2512`, `magistral-medium-2509`) works just as well.\n * Capability inference keys off the family fragment, not this list, so a\n * newer alias is recognized the moment its name matches a fragment in\n * {@link inferVisionCapability} / {@link inferReasoningCapability}.\n */\nexport const MISTRAL_MODELS = {\n /** General-purpose multimodal flagship / mid / small chat aliases. */\n chat: [\"mistral-large-latest\", \"mistral-medium-latest\", \"mistral-small-latest\"],\n /** Dedicated multimodal (vision) aliases — the `pixtral` family. */\n vision: [\"pixtral-large-latest\", \"pixtral-12b\"],\n /** Dedicated reasoning aliases — the `magistral` family. */\n reasoning: [\"magistral-medium-latest\", \"magistral-small-latest\"],\n /** Embeddings model reachable via the OpenAI-compatible `/v1/embeddings`. */\n embedding: [\"mistral-embed\"],\n} as const;\n\n/**\n * Conservative default USD pricing registry (per 1,000,000 tokens),\n * keyed by stable `-latest` alias, surfaced onto every model unless the\n * caller overrides it via SDK-level or per-model `pricing`.\n *\n * These are sane published-list approximations for budgeting / cost-truth\n * out of the box — Mistral revises rates and ships new generations, so\n * pass an explicit `pricing` registry to `new MistralSDK({ pricing })`\n * for billing-grade numbers. Resolution at `model()` time always lets a\n * caller-supplied rate win: per-model `pricing` > SDK `pricing` > these\n * defaults > `undefined`.\n */\nexport const MISTRAL_DEFAULT_PRICING: Record<string, ModelPricing> = {\n \"mistral-large-latest\": { input: 2, output: 6 },\n \"mistral-medium-latest\": { input: 0.4, output: 2 },\n \"mistral-small-latest\": { input: 0.1, output: 0.3 },\n \"pixtral-large-latest\": { input: 2, output: 6 },\n \"pixtral-12b\": { input: 0.15, output: 0.15 },\n \"magistral-medium-latest\": { input: 2, output: 5 },\n \"magistral-small-latest\": { input: 0.5, output: 1.5 },\n \"mistral-embed\": { input: 0.1, output: 0 },\n};\n","import type {\n EmbedderConfig,\n EmbedderContract,\n ModelContract,\n ModelPricing,\n SDKAdapterContract,\n} from \"@warlock.js/ai\";\nimport { OpenAISDK } from \"@warlock.js/ai-openai\";\nimport type { MistralModelConfig, MistralSDKConfig } from \"./config.type\";\nimport {\n inferReasoningCapability,\n inferVisionCapability,\n MISTRAL_DEFAULT_PRICING,\n} from \"./known-models\";\n\n/** Default OpenAI-compatible base URL for the Mistral API. */\nconst MISTRAL_BASE_URL = \"https://api.mistral.ai/v1\";\n\n/** Default provider label stamped onto every model this SDK produces. */\nconst MISTRAL_PROVIDER = \"mistral\";\n\n/**\n * Mistral-backed implementation of `SDKAdapterContract`.\n *\n * **Role.** The package entry point for Mistral AI chat + embeddings.\n * Mistral exposes an **OpenAI-compatible** API (`/v1/chat/completions`,\n * `/v1/embeddings`), so `MistralSDK` is a *thin wrapper* over the\n * battle-tested {@link OpenAISDK} — it does NOT re-implement the wire\n * protocol, streaming loop, tool-call accumulation, structured-output\n * mapping, error wrapping, or token accounting. It constructs one\n * internal `OpenAISDK` pointed at Mistral's `baseURL` with\n * `provider: \"mistral\"`, and delegates `model()` / `embedder()` /\n * `count()` straight to it.\n *\n * **What this wrapper adds on top of the OpenAI adapter:**\n * - **Defaults.** Injects Mistral's `baseURL` + `provider` label and a\n * default {@link MISTRAL_DEFAULT_PRICING} registry so cost truth works\n * out of the box. All are overridable via config.\n * - **Provider-correct capability inference.** Mistral's model names\n * aren't OpenAI names, so the OpenAI prefix lists never match. Before\n * delegating `model()`, this wrapper infers `vision` (the `pixtral`\n * family + recent multimodal generations) and `reasoning` (the\n * `magistral` family + hybrid `mistral-small`) from *this provider's*\n * fragment lists and passes them as explicit overrides — which the\n * inner `OpenAISDK` honors verbatim. A caller-supplied explicit\n * `vision` / `reasoning` still wins.\n *\n * Construct one SDK per account and reuse it everywhere; the single\n * underlying `OpenAI` client (connection pool, auth, rate-limit state)\n * is shared by every model / embedder produced here.\n *\n * **Note — no image generation.** Mistral has no OpenAI-compatible image\n * endpoint, so `image()` is intentionally NOT exposed. The structural\n * absence of the method IS the capability guard (see\n * `SDKAdapterContract.image`): `ai.mistral.image(...)` is a compile-time\n * error rather than a runtime failure.\n *\n * @example\n * const mistral = new MistralSDK({ apiKey: process.env.MISTRAL_API_KEY! });\n * const model = mistral.model({ name: \"mistral-large-latest\", temperature: 0.7 });\n * const embedder = mistral.embedder({ name: \"mistral-embed\" });\n *\n * @example\n * // Compose into an `ai.mistral` namespace for ergonomic agent wiring.\n * const ai = { agent, tool, systemPrompt, mistral: new MistralSDK({ apiKey }) };\n * const reasoner = ai.agent({ model: ai.mistral.model({ name: \"magistral-medium-latest\" }) });\n */\nexport class MistralSDK implements SDKAdapterContract {\n /**\n * The wrapped OpenAI-compatible adapter doing all the real work. Built\n * once in the constructor with Mistral's `baseURL`, `provider` label,\n * and merged pricing registry; every public method delegates to it.\n */\n private readonly openai: OpenAISDK;\n\n public constructor(config: MistralSDKConfig) {\n const { provider, baseURL, pricing, ...clientOptions } = config;\n\n // Caller pricing wins per model id; otherwise fall back to this\n // provider's published-list defaults so cost truth works out of the box.\n const mergedPricing: Record<string, ModelPricing> = {\n ...MISTRAL_DEFAULT_PRICING,\n ...pricing,\n };\n\n this.openai = new OpenAISDK({\n ...clientOptions,\n baseURL: baseURL ?? MISTRAL_BASE_URL,\n provider: provider ?? MISTRAL_PROVIDER,\n pricing: mergedPricing,\n });\n }\n\n /**\n * Build a `ModelContract` for a Mistral chat model.\n *\n * Delegates to the inner `OpenAISDK.model()` but first injects\n * **Mistral-aware capability inference**: when the caller omits\n * `vision` / `reasoning`, they're inferred from this provider's family\n * fragments (`pixtral` → vision, `magistral` / `mistral-small` →\n * reasoning, see `known-models.ts`) and passed down as explicit\n * overrides. Without this step the wrapped OpenAI adapter would check\n * Mistral ids against OpenAI prefixes (`gpt-4o`, `o3`, …) and wrongly\n * report every Mistral model as non-vision / non-reasoning.\n *\n * A caller-supplied explicit `vision` / `reasoning` is preserved as-is\n * (explicit config always wins over inference). Pricing resolution is\n * handled downstream by `OpenAISDK` against the merged registry:\n * per-model `pricing` > SDK registry (caller + Mistral defaults) >\n * `undefined`.\n */\n public model(config: MistralModelConfig): ModelContract {\n const resolvedConfig: MistralModelConfig = {\n ...config,\n vision: config.vision ?? inferVisionCapability(config.name),\n reasoning: config.reasoning ?? inferReasoningCapability(config.name),\n };\n\n return this.openai.model(resolvedConfig);\n }\n\n /**\n * Rough offline token-count estimate. Delegates to the wrapped\n * `OpenAISDK.count()` (the shared character-heuristic from the core\n * package) — good for budgeting / quota guards, not billing. The\n * optional model id is forwarded but currently ignored.\n */\n public async count(text: string, model?: string): Promise<number> {\n return this.openai.count(text, model);\n }\n\n /**\n * Build an `EmbedderContract` bound to this SDK's client. Mistral\n * serves embeddings (`mistral-embed`) through the OpenAI-compatible\n * `/v1/embeddings` endpoint, so this delegates straight to\n * `OpenAISDK.embedder()`.\n *\n * @example\n * const embedder = mistral.embedder({ name: \"mistral-embed\" });\n * const { vector } = await embedder.embed(\"Hello world\");\n */\n public embedder(config: EmbedderConfig): EmbedderContract {\n // `embedder` is optional on the contract but always present on the\n // wrapped OpenAI adapter — assert it for the delegation.\n return this.openai.embedder!(config);\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAwBA,MAAM,4BAA4B;CAChC;CACA;CACA;CACA;AACF;;;;;;;;;;;;;;;;;;;;AAqBA,MAAM,+BAA+B,CAAC,aAAa,eAAe;;;;;;;;;;;;;AAclE,SAAgB,sBAAsB,WAA4B;CAChE,MAAM,aAAa,UAAU,YAAY;CAEzC,OAAO,0BAA0B,MAAM,aAAa,WAAW,SAAS,QAAQ,CAAC;AACnF;;;;;;;;;;;;;AAcA,SAAgB,yBAAyB,WAA4B;CACnE,MAAM,aAAa,UAAU,YAAY;CAEzC,OAAO,6BAA6B,MAAM,aAAa,WAAW,SAAS,QAAQ,CAAC;AACtF;;;;;;;;;;AAWA,MAAa,iBAAiB;;CAE5B,MAAM;EAAC;EAAwB;EAAyB;CAAsB;;CAE9E,QAAQ,CAAC,wBAAwB,aAAa;;CAE9C,WAAW,CAAC,2BAA2B,wBAAwB;;CAE/D,WAAW,CAAC,eAAe;AAC7B;;;;;;;;;;;;;AAcA,MAAa,0BAAwD;CACnE,wBAAwB;EAAE,OAAO;EAAG,QAAQ;CAAE;CAC9C,yBAAyB;EAAE,OAAO;EAAK,QAAQ;CAAE;CACjD,wBAAwB;EAAE,OAAO;EAAK,QAAQ;CAAI;CAClD,wBAAwB;EAAE,OAAO;EAAG,QAAQ;CAAE;CAC9C,eAAe;EAAE,OAAO;EAAM,QAAQ;CAAK;CAC3C,2BAA2B;EAAE,OAAO;EAAG,QAAQ;CAAE;CACjD,0BAA0B;EAAE,OAAO;EAAK,QAAQ;CAAI;CACpD,iBAAiB;EAAE,OAAO;EAAK,QAAQ;CAAE;AAC3C;;;;;ACjHA,MAAM,mBAAmB;;AAGzB,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgDzB,IAAa,aAAb,MAAsD;CAQpD,AAAO,YAAY,QAA0B;EAC3C,MAAM,EAAE,UAAU,SAAS,SAAS,GAAG,kBAAkB;EAIzD,MAAM,gBAA8C;GAClD,GAAG;GACH,GAAG;EACL;EAEA,KAAK,SAAS,IAAIA,gCAAU;GAC1B,GAAG;GACH,SAAS,WAAW;GACpB,UAAU,YAAY;GACtB,SAAS;EACX,CAAC;CACH;;;;;;;;;;;;;;;;;;;CAoBA,AAAO,MAAM,QAA2C;EACtD,MAAM,iBAAqC;GACzC,GAAG;GACH,QAAQ,OAAO,UAAU,sBAAsB,OAAO,IAAI;GAC1D,WAAW,OAAO,aAAa,yBAAyB,OAAO,IAAI;EACrE;EAEA,OAAO,KAAK,OAAO,MAAM,cAAc;CACzC;;;;;;;CAQA,MAAa,MAAM,MAAc,OAAiC;EAChE,OAAO,KAAK,OAAO,MAAM,MAAM,KAAK;CACtC;;;;;;;;;;;CAYA,AAAO,SAAS,QAA0C;EAGxD,OAAO,KAAK,OAAO,SAAU,MAAM;CACrC;AACF"}
@@ -0,0 +1,101 @@
1
+ import { OpenAISDKConfig } from "@warlock.js/ai-openai";
2
+ import { ModelConfig } from "@warlock.js/ai";
3
+
4
+ //#region ../@warlock.js/ai-mistral/src/config.type.d.ts
5
+ /**
6
+ * Configuration for the Mistral SDK adapter.
7
+ *
8
+ * Mistral exposes an **OpenAI-compatible** Chat Completions + Embeddings
9
+ * API, so `MistralSDKConfig` is the OpenAI client options
10
+ * ({@link OpenAISDKConfig}) with this provider's sensible defaults baked
11
+ * in. The whole object is forwarded to the internal `OpenAISDK`, so any
12
+ * upstream client option (`timeout`, `maxRetries`, `defaultHeaders`,
13
+ * `fetch`, …) is accepted verbatim.
14
+ *
15
+ * Defaults injected by `MistralSDK` when omitted:
16
+ * - `baseURL` → `https://api.mistral.ai/v1` (the OpenAI-compatible endpoint).
17
+ * - `provider` → `"mistral"` (flows through to `ModelContract.provider`,
18
+ * `AgentReport.model.provider`, logs, and provider-aware middleware).
19
+ * - `pricing` → merged on top of {@link MISTRAL_DEFAULT_PRICING} so cost
20
+ * accounting works out of the box; a caller entry for the same model id
21
+ * wins.
22
+ *
23
+ * `apiKey` is still required (your Mistral API key) — it has no honest
24
+ * default. Point `baseURL` elsewhere only to reach a Mistral-compatible
25
+ * gateway / proxy.
26
+ *
27
+ * @example
28
+ * new MistralSDK({ apiKey: process.env.MISTRAL_API_KEY! });
29
+ *
30
+ * @example
31
+ * // Override the default pricing for billing-grade cost truth.
32
+ * new MistralSDK({
33
+ * apiKey,
34
+ * pricing: { "mistral-large-latest": { input: 2, output: 6 } },
35
+ * });
36
+ */
37
+ type MistralSDKConfig = OpenAISDKConfig;
38
+ /**
39
+ * Per-model configuration for `MistralSDK.model()`. Extends the neutral
40
+ * {@link ModelConfig} with the same capability overrides the wrapped
41
+ * OpenAI adapter understands — Mistral speaks the same Chat Completions
42
+ * wire, so they pass straight through.
43
+ *
44
+ * The difference from the OpenAI adapter is **inference**: when `vision`
45
+ * / `reasoning` are omitted, `MistralSDK` infers them from this
46
+ * provider's own family fragments (`pixtral` / `magistral`, see
47
+ * `known-models.ts`) rather than the OpenAI prefixes. An explicit
48
+ * `true` / `false` always wins over that inference.
49
+ *
50
+ * @example
51
+ * mistral.model({ name: "mistral-large-latest" }); // vision auto-true
52
+ * mistral.model({ name: "magistral-medium-latest" }); // reasoning auto-true
53
+ * mistral.model({ name: "some-fine-tune", vision: true }); // explicit override
54
+ */
55
+ type MistralModelConfig = ModelConfig & {
56
+ /**
57
+ * Override the auto-inferred vision capability. When omitted, the
58
+ * adapter checks the model id against this provider's multimodal
59
+ * family fragments (`pixtral`, recent `mistral-large` / `mistral-medium`
60
+ * / `ministral-3` generations — see `known-models.ts`). Explicit
61
+ * `true` / `false` always wins over inference.
62
+ */
63
+ vision?: boolean;
64
+ /**
65
+ * Override the auto-inferred reasoning capability. When omitted, the
66
+ * adapter checks the model id against the reasoning fragments
67
+ * (`magistral` family + hybrid `mistral-small`). When the resolved
68
+ * value is `true`, `ModelCallOptions.reasoning.effort` is forwarded as
69
+ * the OpenAI-compatible `reasoning_effort`; when `false` it is dropped.
70
+ * Explicit `true` / `false` always wins over inference.
71
+ */
72
+ reasoning?: boolean;
73
+ /**
74
+ * Override the inferred `structuredOutput` capability, mirroring the
75
+ * wrapped OpenAI adapter. When omitted, treated as capable unless
76
+ * `responseFormat` forces a loose mode (`"json_object"` / `"text"`).
77
+ */
78
+ structuredOutput?: boolean;
79
+ /**
80
+ * Override the wire-level `response_format` the adapter emits when the
81
+ * caller supplies a response schema (`"json_schema"` | `"json_object"`
82
+ * | `"text"`). Forwarded verbatim to the wrapped OpenAI adapter — use
83
+ * for a Mistral model / gateway that rejects strict `json_schema`.
84
+ */
85
+ responseFormat?: "json_schema" | "json_object" | "text";
86
+ /**
87
+ * Opt into PDF / document **input** (default `false`). Forwarded to the
88
+ * wrapped OpenAI adapter, which maps `{ type: "pdf" }` parts to
89
+ * OpenAI-compatible `file` parts.
90
+ */
91
+ pdf?: boolean;
92
+ /**
93
+ * Opt into audio **input** (default `false`). Forwarded to the wrapped
94
+ * OpenAI adapter, which maps `{ type: "audio" }` parts to
95
+ * OpenAI-compatible `input_audio` parts.
96
+ */
97
+ audio?: boolean;
98
+ };
99
+ //#endregion
100
+ export { MistralModelConfig, MistralSDKConfig };
101
+ //# sourceMappingURL=config.type.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.type.d.mts","names":[],"sources":["../../../../../../@warlock.js/ai-mistral/src/config.type.ts"],"mappings":";;;;;;AAmCA;;;;AAA8C;AAmB9C;;;;;;;;;;;;AA0CO;;;;;;;;;;;;;KA7DK,gBAAA,GAAmB,eAAe;;;;;;;;;;;;;;;;;;KAmBlC,kBAAA,GAAqB,WAAW;;;;;;;;EAQ1C,MAAA;;;;;;;;;EASA,SAAA;;;;;;EAMA,gBAAA;;;;;;;EAOA,cAAA;;;;;;EAMA,GAAA;;;;;;EAMA,KAAA;AAAA"}
@@ -0,0 +1,4 @@
1
+ import { MistralModelConfig, MistralSDKConfig } from "./config.type.mjs";
2
+ import { MistralSDK } from "./sdk.mjs";
3
+ import { MISTRAL_DEFAULT_PRICING, MISTRAL_MODELS, inferReasoningCapability, inferVisionCapability } from "./known-models.mjs";
4
+ export { MISTRAL_DEFAULT_PRICING, MISTRAL_MODELS, type MistralModelConfig, MistralSDK, type MistralSDKConfig, inferReasoningCapability, inferVisionCapability };
package/esm/index.mjs ADDED
@@ -0,0 +1,4 @@
1
+ import { MISTRAL_DEFAULT_PRICING, MISTRAL_MODELS, inferReasoningCapability, inferVisionCapability } from "./known-models.mjs";
2
+ import { MistralSDK } from "./sdk.mjs";
3
+
4
+ export { MISTRAL_DEFAULT_PRICING, MISTRAL_MODELS, MistralSDK, inferReasoningCapability, inferVisionCapability };
@@ -0,0 +1,60 @@
1
+ import { ModelPricing } from "@warlock.js/ai";
2
+
3
+ //#region ../@warlock.js/ai-mistral/src/known-models.d.ts
4
+ /**
5
+ * Infer whether a Mistral model id accepts image input (vision) based on
6
+ * the known multimodal-family fragments. Unknown ids default to `false`
7
+ * so passing an image attachment to a text-only model surfaces a clear,
8
+ * agent-side capability error instead of an opaque Mistral 400.
9
+ *
10
+ * @example
11
+ * inferVisionCapability("pixtral-large-latest"); // → true
12
+ * inferVisionCapability("mistral-large-2512"); // → true
13
+ * inferVisionCapability("magistral-medium-latest");// → false
14
+ * inferVisionCapability("mistral-embed"); // → false
15
+ */
16
+ declare function inferVisionCapability(modelName: string): boolean;
17
+ /**
18
+ * Infer whether a Mistral model id is a reasoning model (the `magistral`
19
+ * family plus the hybrid `mistral-small` generation) based on the known
20
+ * fragments. Unknown ids default to `false` so the adapter never forwards
21
+ * an unsupported `reasoning_effort` param to a non-reasoning model.
22
+ *
23
+ * @example
24
+ * inferReasoningCapability("magistral-medium-latest"); // → true
25
+ * inferReasoningCapability("mistral-small-2603"); // → true
26
+ * inferReasoningCapability("mistral-large-latest"); // → false
27
+ * inferReasoningCapability("pixtral-12b"); // → false
28
+ */
29
+ declare function inferReasoningCapability(modelName: string): boolean;
30
+ /**
31
+ * Stable `-latest` alias ids for the headline Mistral chat / embeddings
32
+ * models, grouped by role. Convenience constants only — `mistral.model()`
33
+ * accepts any id string, so a version-pinned id
34
+ * (`mistral-large-2512`, `magistral-medium-2509`) works just as well.
35
+ * Capability inference keys off the family fragment, not this list, so a
36
+ * newer alias is recognized the moment its name matches a fragment in
37
+ * {@link inferVisionCapability} / {@link inferReasoningCapability}.
38
+ */
39
+ declare const MISTRAL_MODELS: {
40
+ /** General-purpose multimodal flagship / mid / small chat aliases. */readonly chat: readonly ["mistral-large-latest", "mistral-medium-latest", "mistral-small-latest"]; /** Dedicated multimodal (vision) aliases — the `pixtral` family. */
41
+ readonly vision: readonly ["pixtral-large-latest", "pixtral-12b"]; /** Dedicated reasoning aliases — the `magistral` family. */
42
+ readonly reasoning: readonly ["magistral-medium-latest", "magistral-small-latest"]; /** Embeddings model reachable via the OpenAI-compatible `/v1/embeddings`. */
43
+ readonly embedding: readonly ["mistral-embed"];
44
+ };
45
+ /**
46
+ * Conservative default USD pricing registry (per 1,000,000 tokens),
47
+ * keyed by stable `-latest` alias, surfaced onto every model unless the
48
+ * caller overrides it via SDK-level or per-model `pricing`.
49
+ *
50
+ * These are sane published-list approximations for budgeting / cost-truth
51
+ * out of the box — Mistral revises rates and ships new generations, so
52
+ * pass an explicit `pricing` registry to `new MistralSDK({ pricing })`
53
+ * for billing-grade numbers. Resolution at `model()` time always lets a
54
+ * caller-supplied rate win: per-model `pricing` > SDK `pricing` > these
55
+ * defaults > `undefined`.
56
+ */
57
+ declare const MISTRAL_DEFAULT_PRICING: Record<string, ModelPricing>;
58
+ //#endregion
59
+ export { MISTRAL_DEFAULT_PRICING, MISTRAL_MODELS, inferReasoningCapability, inferVisionCapability };
60
+ //# sourceMappingURL=known-models.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"known-models.d.mts","names":[],"sources":["../../../../../../@warlock.js/ai-mistral/src/known-models.ts"],"mappings":";;;;;AAgEA;;;;AAAuD;AAkBvD;;;;AAA0D;iBAlB1C,qBAAA,CAAsB,SAAiB;;;;;;;;;;AAwDvD;;;iBAtCgB,wBAAA,CAAyB,SAAiB;AAsCO;;;;;;;;;AAAA,cAvBpD,cAAA;;;;;;;;;;;;;;;;;;cAuBA,uBAAA,EAAyB,MAAM,SAAS,YAAA"}