@x12i/ai-profiles 4.5.0 → 5.0.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.
Files changed (39) hide show
  1. package/README.md +19 -6
  2. package/dist/data/reasoning-coverage.json +499 -0
  3. package/dist/data/reasoning-directives.json +7562 -0
  4. package/dist/errors.d.ts +1 -1
  5. package/dist/errors.d.ts.map +1 -1
  6. package/dist/errors.js.map +1 -1
  7. package/dist/index.d.ts +2 -2
  8. package/dist/index.d.ts.map +1 -1
  9. package/dist/index.js +1 -1
  10. package/dist/index.js.map +1 -1
  11. package/dist/reasoning/mergeReasoningBody.d.ts +7 -0
  12. package/dist/reasoning/mergeReasoningBody.d.ts.map +1 -0
  13. package/dist/reasoning/mergeReasoningBody.js +50 -0
  14. package/dist/reasoning/mergeReasoningBody.js.map +1 -0
  15. package/dist/reasoning/resolveReasoningDocument.d.ts +4 -0
  16. package/dist/reasoning/resolveReasoningDocument.d.ts.map +1 -0
  17. package/dist/reasoning/resolveReasoningDocument.js +153 -0
  18. package/dist/reasoning/resolveReasoningDocument.js.map +1 -0
  19. package/dist/reasoning/types.d.ts +75 -22
  20. package/dist/reasoning/types.d.ts.map +1 -1
  21. package/dist/reasoning/types.js +19 -21
  22. package/dist/reasoning/types.js.map +1 -1
  23. package/dist/reasoning/validateReasoningDirectives.d.ts +9 -0
  24. package/dist/reasoning/validateReasoningDirectives.d.ts.map +1 -0
  25. package/dist/reasoning/validateReasoningDirectives.js +324 -0
  26. package/dist/reasoning/validateReasoningDirectives.js.map +1 -0
  27. package/dist/resolveReasoning.d.ts +5 -5
  28. package/dist/resolveReasoning.d.ts.map +1 -1
  29. package/dist/resolveReasoning.js +7 -75
  30. package/dist/resolveReasoning.js.map +1 -1
  31. package/package.json +2 -1
  32. package/dist/reasoning/bedrockDirective.d.ts +0 -18
  33. package/dist/reasoning/bedrockDirective.d.ts.map +0 -1
  34. package/dist/reasoning/bedrockDirective.js +0 -131
  35. package/dist/reasoning/bedrockDirective.js.map +0 -1
  36. package/dist/reasoning/openRouterDirective.d.ts +0 -18
  37. package/dist/reasoning/openRouterDirective.d.ts.map +0 -1
  38. package/dist/reasoning/openRouterDirective.js +0 -136
  39. package/dist/reasoning/openRouterDirective.js.map +0 -1
package/README.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  > **v4.4.1** adds `@x12i/ai-profiles/browser` for Vite/UI. Explore via `npm run ui` (AI Profiles tab).
4
4
 
5
+ > **v5.0** replaces `resolveReasoning` with a target-specific directive (`applied`, `degraded`, `ignored`). `openai` means the Responses API. Pin **`"@x12i/ai-profiles": "^5.0.0"`**. See [CHANGELOG.md](CHANGELOG.md).
6
+
5
7
  # @x12i/ai-profiles
6
8
 
7
9
  Resolve AI profile names into concrete model choices. The package ships JSON in `src/data/` as the offline fallback. By default, registry data is fetched from public assets, validated, and cached in memory.
@@ -291,7 +293,8 @@ npm install @x12i/ai-profiles
291
293
  | `resolveBundledCatalogModelDetails(slug, options?)` | Yes | Same as above but throws `UNKNOWN_MODEL` on miss |
292
294
  | `resolveCatalogModelDetails(slug, options?)` | No (async) | Rich catalog snapshot with optional remote catalog refresh |
293
295
  | `isReasoningModel(input, options?)` | Yes | `true`/`false` for supported inputs (throws `UNKNOWN_MODEL` on unknown concrete models) |
294
- | `resolveReasoning({ transport, model, effort })` | Yes | Opaque reasoning directive for `openrouter` or `bedrock`. `supported: false` means send no reasoning fields |
296
+ | `resolveReasoning({ target, model, effort })` | Yes | Bundled directive for `openrouter`, `bedrock`, or `openai` (Responses). `outcome` is `applied`, `degraded`, or `ignored`. Throws `AIProfilesError` for unknown models and incomplete mappings |
297
+ | `mergeReasoningBody(targetBody, directiveBody)` | Yes | Deep-merge a directive body. Objects merge, arrays and scalars replace, inputs are not mutated |
295
298
  | `resolveAIProfile(input, options?)` | No (async) | Resolve an explicit `profile/choice` key → model, pricing, runtime. Pass `includeSecondary: true` to attach `secondary`; `includeCatalog: true` to attach full `catalogModel`. |
296
299
  | `resolveSecondaryModel(input, options?)` | No (async) | Resolve primary choice + optional companion `secondary` from profile `secondary` refs |
297
300
  | `getSecondaryForResolvedProfile(resolved, registry, catalog?)` | Yes | Secondary for an already-resolved primary (no extra I/O when catalog is passed) |
@@ -356,8 +359,8 @@ import {
356
359
  ensureConcreteModel,
357
360
  isKnownProfileInput,
358
361
  isReasoningModel,
362
+ mergeReasoningBody,
359
363
  resolveReasoning,
360
- toAbstractEffort,
361
364
  resolveBundledInput,
362
365
  resolveBundledAIProfile,
363
366
  applyModelRouting,
@@ -394,13 +397,19 @@ isReasoningModel("cheap/default"); // true (catalog marks gemini-2.5-flash-lite
394
397
  isReasoningModel("google/gemini-2.5-flash-lite"); // false
395
398
 
396
399
  const resolved = resolveBundledAIProfile("deep/default", { catalogLane: "text" });
400
+ let prompt = "Classify this ticket.";
401
+ let body: Record<string, unknown> = { messages: [{ role: "user", content: prompt }] };
397
402
  const directive = resolveReasoning({
398
- transport: "openrouter",
403
+ target: "openrouter",
399
404
  model: resolved.invocation.openrouter.modelId,
400
- effort: toAbstractEffort(resolved.runtime.reasoningEffort),
405
+ effort: resolved.runtime.reasoningEffort ?? "medium",
401
406
  });
402
- // When directive.supported is false, send no reasoning fields.
403
- // directive.body merges onto the OpenRouter request. Keys stay opaque to the caller.
407
+ // Skip this block when the caller already set reasoning. Explicit config wins.
408
+ if (directive.outcome !== "ignored") {
409
+ if (directive.model) body.model = directive.model;
410
+ if (directive.promptPrefix) prompt = directive.promptPrefix + prompt;
411
+ body = mergeReasoningBody(body, directive.body);
412
+ }
404
413
 
405
414
  const caps = lookupBundledCatalogCaps({
406
415
  provider: "openrouter",
@@ -415,6 +424,10 @@ const routed = applyModelRouting(
415
424
  );
416
425
  ```
417
426
 
427
+ `reasoningTextPaths` and `usage.reasoningTokenPaths` are JSON Pointers. `*` means every array element. Both lists are ordered alternatives: use the first path that yields a value, and do not sum usage paths. `streamReasoningKeys` are exact keys on a flat delta (`choices[*].delta` for OpenRouter). `streamReasoningPaths` are pointers into one stream event (Bedrock `contentBlockDelta`, or an OpenAI `response.reasoning_summary_text.delta` event). A directive fills only one of those stream fields. `stripFromHistoryPaths` lists fields that are safe to delete from a replayed message. OpenRouter `reasoning_details`, Bedrock `reasoningContent` signatures, and Responses reasoning items stay. `stripThinkTags` separates a whole `<think>...</think>` section from answer text, including tags split across chunks; an unclosed section at end of stream stays out of the answer. It is false unless a mapping says the model puts thoughts in answer text.
428
+
429
+ `"openai"` is `POST https://api.openai.com/v1/responses`. Do not send Chat Completions `reasoning_effort`. The resolver cannot see `max_output_tokens`, Bedrock `maxTokens`, or sampling parameters. Those constraints are on the mapping provenance in `reasoning-directives.json` and in [CHANGELOG.md](CHANGELOG.md). Coverage for 5.0.0 is that changelog, not every model on a provider.
430
+
418
431
  For the same profile-first order with optional remote registry/catalog (`source: "auto"` / `"remote"` / `"bundled"`), use **`resolveInput`**:
419
432
 
420
433
  ```ts
@@ -0,0 +1,499 @@
1
+ {
2
+ "schema": "x12i.ai-profiles.reasoning-coverage",
3
+ "version": "5.0.0",
4
+ "verifiedAt": "2026-09-23",
5
+ "notes": [
6
+ "OpenRouter coverage is the bundled text catalog. Bedrock and OpenAI coverage are explicit ids only.",
7
+ "supports_max_tokens models and capabilities.reasoning rows without a control object are gaps, not ignored.",
8
+ "No universal token-budget table is emitted.",
9
+ "amazon.nova-pro is not mapped. Nova 2 reasoningConfig is not that model's contract.",
10
+ "Claude Mythos 5.1 is in aws-ai-availability but has no catalog row, so it is not assigned."
11
+ ],
12
+ "counts": {
13
+ "openrouterEffort": 120,
14
+ "openrouterIgnored": 162,
15
+ "openrouterGaps": 65,
16
+ "bedrockEffort": 3,
17
+ "bedrockGaps": 1,
18
+ "openaiEffort": 5,
19
+ "openaiIgnored": 2
20
+ },
21
+ "profiles": [
22
+ "bedrock.adaptive.low-medium-high",
23
+ "bedrock.adaptive.low-medium-high-max",
24
+ "openai.responses.ignored",
25
+ "openai.responses.low-medium-high-max",
26
+ "or.effort.high",
27
+ "or.effort.high.xhigh",
28
+ "or.effort.high.xhigh.max",
29
+ "or.effort.low.high",
30
+ "or.effort.low.high.max",
31
+ "or.effort.low.medium",
32
+ "or.effort.low.medium.high",
33
+ "or.effort.low.medium.high.max",
34
+ "or.effort.low.medium.high.xhigh",
35
+ "or.effort.low.medium.high.xhigh.max",
36
+ "or.effort.low.medium.xhigh",
37
+ "or.effort.medium.high",
38
+ "or.effort.medium.high.xhigh",
39
+ "or.effort.medium.xhigh",
40
+ "or.effort.minimal.low.medium.high",
41
+ "or.effort.minimal.low.medium.high.max",
42
+ "or.effort.minimal.low.medium.high.xhigh",
43
+ "or.effort.minimal.low.medium.high.xhigh.max",
44
+ "or.ignored.no-selectable-control",
45
+ "or.ignored.non-reasoning"
46
+ ],
47
+ "bedrock": [
48
+ {
49
+ "modelId": "anthropic.claude-fable-5-1",
50
+ "catalogModelId": "anthropic/claude-fable-5.1",
51
+ "profileId": "bedrock.adaptive.low-medium-high"
52
+ },
53
+ {
54
+ "modelId": "us.anthropic.claude-opus-5",
55
+ "catalogModelId": "anthropic/claude-opus-5",
56
+ "profileId": "bedrock.adaptive.low-medium-high-max"
57
+ },
58
+ {
59
+ "modelId": "us.anthropic.claude-sonnet-5",
60
+ "catalogModelId": "anthropic/claude-sonnet-5",
61
+ "profileId": "bedrock.adaptive.low-medium-high"
62
+ }
63
+ ],
64
+ "openai": [
65
+ {
66
+ "modelId": "gpt-4o",
67
+ "catalogModelId": "openai/gpt-4o",
68
+ "profileId": "openai.responses.ignored"
69
+ },
70
+ {
71
+ "modelId": "gpt-4o-mini",
72
+ "catalogModelId": "openai/gpt-4o-mini",
73
+ "profileId": "openai.responses.ignored"
74
+ },
75
+ {
76
+ "modelId": "gpt-5.4",
77
+ "catalogModelId": "openai/gpt-5.4",
78
+ "profileId": "openai.responses.low-medium-high-max"
79
+ },
80
+ {
81
+ "modelId": "gpt-5.5",
82
+ "catalogModelId": "openai/gpt-5.5",
83
+ "profileId": "openai.responses.low-medium-high-max"
84
+ },
85
+ {
86
+ "modelId": "gpt-5.6-luna",
87
+ "catalogModelId": "openai/gpt-5.6-luna",
88
+ "profileId": "openai.responses.low-medium-high-max"
89
+ },
90
+ {
91
+ "modelId": "gpt-5.6-sol",
92
+ "catalogModelId": "openai/gpt-5.6-sol",
93
+ "profileId": "openai.responses.low-medium-high-max"
94
+ },
95
+ {
96
+ "modelId": "gpt-5.6-terra",
97
+ "catalogModelId": "openai/gpt-5.6-terra",
98
+ "profileId": "openai.responses.low-medium-high-max"
99
+ }
100
+ ],
101
+ "gaps": [
102
+ {
103
+ "target": "bedrock",
104
+ "modelId": "anthropic.claude-haiku-4-5",
105
+ "catalogModelId": "anthropic/claude-haiku-4.5",
106
+ "reason": "Claude Haiku 4.5 uses extended thinking budget_tokens, which must be lower than the caller maxTokens. No documented five-level budget table exists, so no directive is emitted."
107
+ },
108
+ {
109
+ "target": "openrouter",
110
+ "modelId": "~anthropic/claude-haiku-latest",
111
+ "catalogModelId": "~anthropic/claude-haiku-latest",
112
+ "reason": "capabilities.reasoning is true but the models API sent no reasoning control object."
113
+ },
114
+ {
115
+ "target": "openrouter",
116
+ "modelId": "amazon/nova-2-lite-v1",
117
+ "catalogModelId": "amazon/nova-2-lite-v1",
118
+ "reason": "capabilities.reasoning is true but the models API sent no reasoning control object."
119
+ },
120
+ {
121
+ "target": "openrouter",
122
+ "modelId": "anthropic/claude-haiku-4.5",
123
+ "catalogModelId": "anthropic/claude-haiku-4.5",
124
+ "reason": "capabilities.reasoning is true but the models API sent no reasoning control object."
125
+ },
126
+ {
127
+ "target": "openrouter",
128
+ "modelId": "anthropic/claude-opus-4.1",
129
+ "catalogModelId": "anthropic/claude-opus-4.1",
130
+ "reason": "capabilities.reasoning is true but the models API sent no reasoning control object."
131
+ },
132
+ {
133
+ "target": "openrouter",
134
+ "modelId": "anthropic/claude-opus-4.5",
135
+ "catalogModelId": "anthropic/claude-opus-4.5",
136
+ "reason": "capabilities.reasoning is true but the models API sent no reasoning control object."
137
+ },
138
+ {
139
+ "target": "openrouter",
140
+ "modelId": "anthropic/claude-sonnet-4",
141
+ "catalogModelId": "anthropic/claude-sonnet-4",
142
+ "reason": "capabilities.reasoning is true but the models API sent no reasoning control object."
143
+ },
144
+ {
145
+ "target": "openrouter",
146
+ "modelId": "anthropic/claude-sonnet-4.5",
147
+ "catalogModelId": "anthropic/claude-sonnet-4.5",
148
+ "reason": "capabilities.reasoning is true but the models API sent no reasoning control object."
149
+ },
150
+ {
151
+ "target": "openrouter",
152
+ "modelId": "baidu/ernie-4.5-vl-424b-a47b",
153
+ "catalogModelId": "baidu/ernie-4.5-vl-424b-a47b",
154
+ "reason": "capabilities.reasoning is true but the models API sent no reasoning control object."
155
+ },
156
+ {
157
+ "target": "openrouter",
158
+ "modelId": "bytedance-seed/seed-1.6",
159
+ "catalogModelId": "bytedance-seed/seed-1.6",
160
+ "reason": "capabilities.reasoning is true but the models API sent no reasoning control object."
161
+ },
162
+ {
163
+ "target": "openrouter",
164
+ "modelId": "bytedance-seed/seed-1.6-flash",
165
+ "catalogModelId": "bytedance-seed/seed-1.6-flash",
166
+ "reason": "capabilities.reasoning is true but the models API sent no reasoning control object."
167
+ },
168
+ {
169
+ "target": "openrouter",
170
+ "modelId": "bytedance-seed/seed-2-1-turbo",
171
+ "catalogModelId": "bytedance-seed/seed-2-1-turbo",
172
+ "reason": "capabilities.reasoning is true but the models API sent no reasoning control object."
173
+ },
174
+ {
175
+ "target": "openrouter",
176
+ "modelId": "cohere/command-a-plus",
177
+ "catalogModelId": "cohere/command-a-plus",
178
+ "reason": "capabilities.reasoning is true but the models API sent no reasoning control object."
179
+ },
180
+ {
181
+ "target": "openrouter",
182
+ "modelId": "deepseek/deepseek-chat-v3.1",
183
+ "catalogModelId": "deepseek/deepseek-chat-v3.1",
184
+ "reason": "capabilities.reasoning is true but the models API sent no reasoning control object."
185
+ },
186
+ {
187
+ "target": "openrouter",
188
+ "modelId": "deepseek/deepseek-r1-distill-llama-70b",
189
+ "catalogModelId": "deepseek/deepseek-r1-distill-llama-70b",
190
+ "reason": "capabilities.reasoning is true but the models API sent no reasoning control object."
191
+ },
192
+ {
193
+ "target": "openrouter",
194
+ "modelId": "deepseek/deepseek-v3.1-terminus",
195
+ "catalogModelId": "deepseek/deepseek-v3.1-terminus",
196
+ "reason": "capabilities.reasoning is true but the models API sent no reasoning control object."
197
+ },
198
+ {
199
+ "target": "openrouter",
200
+ "modelId": "deepseek/deepseek-v3.2-exp",
201
+ "catalogModelId": "deepseek/deepseek-v3.2-exp",
202
+ "reason": "capabilities.reasoning is true but the models API sent no reasoning control object."
203
+ },
204
+ {
205
+ "target": "openrouter",
206
+ "modelId": "google/gemini-2.5-flash",
207
+ "catalogModelId": "google/gemini-2.5-flash",
208
+ "reason": "capabilities.reasoning is true but the models API sent no reasoning control object."
209
+ },
210
+ {
211
+ "target": "openrouter",
212
+ "modelId": "google/gemini-2.5-flash-lite",
213
+ "catalogModelId": "google/gemini-2.5-flash-lite",
214
+ "reason": "capabilities.reasoning is true but the models API sent no reasoning control object."
215
+ },
216
+ {
217
+ "target": "openrouter",
218
+ "modelId": "meituan/longcat-2.0",
219
+ "catalogModelId": "meituan/longcat-2.0",
220
+ "reason": "Model accepts reasoning.max_tokens and has no effort allowlist. No per-model token budgets are documented, so no budget directive is emitted."
221
+ },
222
+ {
223
+ "target": "openrouter",
224
+ "modelId": "minimax/minimax-m1",
225
+ "catalogModelId": "minimax/minimax-m1",
226
+ "reason": "capabilities.reasoning is true but the models API sent no reasoning control object."
227
+ },
228
+ {
229
+ "target": "openrouter",
230
+ "modelId": "minimax/minimax-m3",
231
+ "catalogModelId": "minimax/minimax-m3",
232
+ "reason": "capabilities.reasoning is true but the models API sent no reasoning control object."
233
+ },
234
+ {
235
+ "target": "openrouter",
236
+ "modelId": "nousresearch/hermes-4-405b",
237
+ "catalogModelId": "nousresearch/hermes-4-405b",
238
+ "reason": "capabilities.reasoning is true but the models API sent no reasoning control object."
239
+ },
240
+ {
241
+ "target": "openrouter",
242
+ "modelId": "nvidia/nemotron-3-nano-30b-a3b",
243
+ "catalogModelId": "nvidia/nemotron-3-nano-30b-a3b",
244
+ "reason": "capabilities.reasoning is true but the models API sent no reasoning control object."
245
+ },
246
+ {
247
+ "target": "openrouter",
248
+ "modelId": "nvidia/nemotron-3.5-lightning",
249
+ "catalogModelId": "nvidia/nemotron-3.5-lightning",
250
+ "reason": "capabilities.reasoning is true but the models API sent no reasoning control object."
251
+ },
252
+ {
253
+ "target": "openrouter",
254
+ "modelId": "openai/o1",
255
+ "catalogModelId": "openai/o1",
256
+ "reason": "capabilities.reasoning is true but the models API sent no reasoning control object."
257
+ },
258
+ {
259
+ "target": "openrouter",
260
+ "modelId": "openai/o1-pro",
261
+ "catalogModelId": "openai/o1-pro",
262
+ "reason": "capabilities.reasoning is true but the models API sent no reasoning control object."
263
+ },
264
+ {
265
+ "target": "openrouter",
266
+ "modelId": "openai/o3",
267
+ "catalogModelId": "openai/o3",
268
+ "reason": "capabilities.reasoning is true but the models API sent no reasoning control object."
269
+ },
270
+ {
271
+ "target": "openrouter",
272
+ "modelId": "openai/o3-mini",
273
+ "catalogModelId": "openai/o3-mini",
274
+ "reason": "capabilities.reasoning is true but the models API sent no reasoning control object."
275
+ },
276
+ {
277
+ "target": "openrouter",
278
+ "modelId": "openai/o3-pro",
279
+ "catalogModelId": "openai/o3-pro",
280
+ "reason": "capabilities.reasoning is true but the models API sent no reasoning control object."
281
+ },
282
+ {
283
+ "target": "openrouter",
284
+ "modelId": "openai/o4-mini",
285
+ "catalogModelId": "openai/o4-mini",
286
+ "reason": "capabilities.reasoning is true but the models API sent no reasoning control object."
287
+ },
288
+ {
289
+ "target": "openrouter",
290
+ "modelId": "openrouter/bodybuilder",
291
+ "catalogModelId": "openrouter/bodybuilder",
292
+ "reason": "OpenRouter router ids omit ModelReasoning for routing, not as a verified non-reasoning model."
293
+ },
294
+ {
295
+ "target": "openrouter",
296
+ "modelId": "openrouter/free",
297
+ "catalogModelId": "openrouter/free",
298
+ "reason": "OpenRouter router ids omit ModelReasoning for routing, not as a verified non-reasoning model."
299
+ },
300
+ {
301
+ "target": "openrouter",
302
+ "modelId": "openrouter/fusion",
303
+ "catalogModelId": "openrouter/fusion",
304
+ "reason": "OpenRouter router ids omit ModelReasoning for routing, not as a verified non-reasoning model."
305
+ },
306
+ {
307
+ "target": "openrouter",
308
+ "modelId": "openrouter/pareto-code",
309
+ "catalogModelId": "openrouter/pareto-code",
310
+ "reason": "OpenRouter router ids omit ModelReasoning for routing, not as a verified non-reasoning model."
311
+ },
312
+ {
313
+ "target": "openrouter",
314
+ "modelId": "perceptron/perceptron-mk1",
315
+ "catalogModelId": "perceptron/perceptron-mk1",
316
+ "reason": "capabilities.reasoning is true but the models API sent no reasoning control object."
317
+ },
318
+ {
319
+ "target": "openrouter",
320
+ "modelId": "perplexity/sonar-deep-research",
321
+ "catalogModelId": "perplexity/sonar-deep-research",
322
+ "reason": "capabilities.reasoning is true but the models API sent no reasoning control object."
323
+ },
324
+ {
325
+ "target": "openrouter",
326
+ "modelId": "perplexity/sonar-reasoning-pro",
327
+ "catalogModelId": "perplexity/sonar-reasoning-pro",
328
+ "reason": "capabilities.reasoning is true but the models API sent no reasoning control object."
329
+ },
330
+ {
331
+ "target": "openrouter",
332
+ "modelId": "qwen/qwen3-14b",
333
+ "catalogModelId": "qwen/qwen3-14b",
334
+ "reason": "capabilities.reasoning is true but the models API sent no reasoning control object."
335
+ },
336
+ {
337
+ "target": "openrouter",
338
+ "modelId": "qwen/qwen3-235b-a22b",
339
+ "catalogModelId": "qwen/qwen3-235b-a22b",
340
+ "reason": "capabilities.reasoning is true but the models API sent no reasoning control object."
341
+ },
342
+ {
343
+ "target": "openrouter",
344
+ "modelId": "qwen/qwen3-32b",
345
+ "catalogModelId": "qwen/qwen3-32b",
346
+ "reason": "capabilities.reasoning is true but the models API sent no reasoning control object."
347
+ },
348
+ {
349
+ "target": "openrouter",
350
+ "modelId": "qwen/qwen3-max-thinking",
351
+ "catalogModelId": "qwen/qwen3-max-thinking",
352
+ "reason": "capabilities.reasoning is true but the models API sent no reasoning control object."
353
+ },
354
+ {
355
+ "target": "openrouter",
356
+ "modelId": "qwen/qwen3.5-122b-a10b",
357
+ "catalogModelId": "qwen/qwen3.5-122b-a10b",
358
+ "reason": "capabilities.reasoning is true but the models API sent no reasoning control object."
359
+ },
360
+ {
361
+ "target": "openrouter",
362
+ "modelId": "qwen/qwen3.5-27b",
363
+ "catalogModelId": "qwen/qwen3.5-27b",
364
+ "reason": "capabilities.reasoning is true but the models API sent no reasoning control object."
365
+ },
366
+ {
367
+ "target": "openrouter",
368
+ "modelId": "qwen/qwen3.5-35b-a3b",
369
+ "catalogModelId": "qwen/qwen3.5-35b-a3b",
370
+ "reason": "capabilities.reasoning is true but the models API sent no reasoning control object."
371
+ },
372
+ {
373
+ "target": "openrouter",
374
+ "modelId": "qwen/qwen3.5-397b-a17b",
375
+ "catalogModelId": "qwen/qwen3.5-397b-a17b",
376
+ "reason": "capabilities.reasoning is true but the models API sent no reasoning control object."
377
+ },
378
+ {
379
+ "target": "openrouter",
380
+ "modelId": "qwen/qwen3.5-9b",
381
+ "catalogModelId": "qwen/qwen3.5-9b",
382
+ "reason": "capabilities.reasoning is true but the models API sent no reasoning control object."
383
+ },
384
+ {
385
+ "target": "openrouter",
386
+ "modelId": "qwen/qwen3.5-flash-02-23",
387
+ "catalogModelId": "qwen/qwen3.5-flash-02-23",
388
+ "reason": "capabilities.reasoning is true but the models API sent no reasoning control object."
389
+ },
390
+ {
391
+ "target": "openrouter",
392
+ "modelId": "qwen/qwen3.5-plus-02-15",
393
+ "catalogModelId": "qwen/qwen3.5-plus-02-15",
394
+ "reason": "capabilities.reasoning is true but the models API sent no reasoning control object."
395
+ },
396
+ {
397
+ "target": "openrouter",
398
+ "modelId": "qwen/qwen3.5-plus-20260420",
399
+ "catalogModelId": "qwen/qwen3.5-plus-20260420",
400
+ "reason": "capabilities.reasoning is true but the models API sent no reasoning control object."
401
+ },
402
+ {
403
+ "target": "openrouter",
404
+ "modelId": "qwen/qwen3.6-flash",
405
+ "catalogModelId": "qwen/qwen3.6-flash",
406
+ "reason": "capabilities.reasoning is true but the models API sent no reasoning control object."
407
+ },
408
+ {
409
+ "target": "openrouter",
410
+ "modelId": "qwen/qwen3.6-plus",
411
+ "catalogModelId": "qwen/qwen3.6-plus",
412
+ "reason": "capabilities.reasoning is true but the models API sent no reasoning control object."
413
+ },
414
+ {
415
+ "target": "openrouter",
416
+ "modelId": "qwen/qwen3.7-flash",
417
+ "catalogModelId": "qwen/qwen3.7-flash",
418
+ "reason": "Model accepts reasoning.max_tokens and has no effort allowlist. No per-model token budgets are documented, so no budget directive is emitted."
419
+ },
420
+ {
421
+ "target": "openrouter",
422
+ "modelId": "qwen/qwen3.8-flash",
423
+ "catalogModelId": "qwen/qwen3.8-flash",
424
+ "reason": "Model accepts reasoning.max_tokens and has no effort allowlist. No per-model token budgets are documented, so no budget directive is emitted."
425
+ },
426
+ {
427
+ "target": "openrouter",
428
+ "modelId": "qwen/qwen3.8-omni-flash",
429
+ "catalogModelId": "qwen/qwen3.8-omni-flash",
430
+ "reason": "Model accepts reasoning.max_tokens and has no effort allowlist. No per-model token budgets are documented, so no budget directive is emitted."
431
+ },
432
+ {
433
+ "target": "openrouter",
434
+ "modelId": "tencent/hunyuan-a13b-instruct",
435
+ "catalogModelId": "tencent/hunyuan-a13b-instruct",
436
+ "reason": "capabilities.reasoning is true but the models API sent no reasoning control object."
437
+ },
438
+ {
439
+ "target": "openrouter",
440
+ "modelId": "xiaomi/mimo-v2.5",
441
+ "catalogModelId": "xiaomi/mimo-v2.5",
442
+ "reason": "capabilities.reasoning is true but the models API sent no reasoning control object."
443
+ },
444
+ {
445
+ "target": "openrouter",
446
+ "modelId": "xiaomi/mimo-v2.5-pro",
447
+ "catalogModelId": "xiaomi/mimo-v2.5-pro",
448
+ "reason": "capabilities.reasoning is true but the models API sent no reasoning control object."
449
+ },
450
+ {
451
+ "target": "openrouter",
452
+ "modelId": "xiaomi/mimo-v2.6-flash",
453
+ "catalogModelId": "xiaomi/mimo-v2.6-flash",
454
+ "reason": "capabilities.reasoning is true but the models API sent no reasoning control object."
455
+ },
456
+ {
457
+ "target": "openrouter",
458
+ "modelId": "xiaomi/mimo-v2.6-pro",
459
+ "catalogModelId": "xiaomi/mimo-v2.6-pro",
460
+ "reason": "capabilities.reasoning is true but the models API sent no reasoning control object."
461
+ },
462
+ {
463
+ "target": "openrouter",
464
+ "modelId": "xiaomi/mimo-v2.6-pro-ultraspeed",
465
+ "catalogModelId": "xiaomi/mimo-v2.6-pro-ultraspeed",
466
+ "reason": "capabilities.reasoning is true but the models API sent no reasoning control object."
467
+ },
468
+ {
469
+ "target": "openrouter",
470
+ "modelId": "z-ai/glm-4.5",
471
+ "catalogModelId": "z-ai/glm-4.5",
472
+ "reason": "capabilities.reasoning is true but the models API sent no reasoning control object."
473
+ },
474
+ {
475
+ "target": "openrouter",
476
+ "modelId": "z-ai/glm-4.5-air",
477
+ "catalogModelId": "z-ai/glm-4.5-air",
478
+ "reason": "capabilities.reasoning is true but the models API sent no reasoning control object."
479
+ },
480
+ {
481
+ "target": "openrouter",
482
+ "modelId": "z-ai/glm-4.5v",
483
+ "catalogModelId": "z-ai/glm-4.5v",
484
+ "reason": "capabilities.reasoning is true but the models API sent no reasoning control object."
485
+ },
486
+ {
487
+ "target": "openrouter",
488
+ "modelId": "z-ai/glm-4.6",
489
+ "catalogModelId": "z-ai/glm-4.6",
490
+ "reason": "capabilities.reasoning is true but the models API sent no reasoning control object."
491
+ },
492
+ {
493
+ "target": "openrouter",
494
+ "modelId": "z-ai/glm-4.6v",
495
+ "catalogModelId": "z-ai/glm-4.6v",
496
+ "reason": "capabilities.reasoning is true but the models API sent no reasoning control object."
497
+ }
498
+ ]
499
+ }