opencode-cache-engine 0.4.4 → 0.4.5
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/README.md +47 -31
- package/docs/cache-policy-inventory.md +32 -9
- package/package.json +1 -1
- package/src/cache-policy-core.mjs +57 -5
- package/test/cache-engine.test.mjs +109 -4
package/README.md
CHANGED
|
@@ -32,7 +32,7 @@ The plugin currently has four cache-policy families:
|
|
|
32
32
|
unchanged. GPT-6 and future 5.6+/6+/7+ versions resolve through the same
|
|
33
33
|
documented boundary.
|
|
34
34
|
* **GLM-5.3 and later** — GLM implicit-cache baseline and diagnostics; GLM-5.3 additionally uses a narrow, content-preserving `<env>` relocation overlay.
|
|
35
|
-
* **MiMo
|
|
35
|
+
* **MiMo V2.6 and later** — MiMo implicit-cache baseline and diagnostics; MiMo V2.6 Flash/Pro additionally use a narrow, content-preserving `<env>` relocation overlay.
|
|
36
36
|
|
|
37
37
|
Family classification is not hard-coded in the runtime. A pure policy registry
|
|
38
38
|
and resolver in `src/cache-policy-core.mjs` returns a structured result
|
|
@@ -42,7 +42,7 @@ the single runtime source of policy classification. The first-party research
|
|
|
42
42
|
behind each registry entry is recorded in
|
|
43
43
|
[docs/cache-policy-inventory.md](docs/cache-policy-inventory.md).
|
|
44
44
|
|
|
45
|
-
For MiMo
|
|
45
|
+
For the MiMo V2.6-and-later family and the GLM-5.3-and-later family, CacheEngine adds its deterministic
|
|
46
46
|
`x-session-id` request header only when OpenCode identifies the actual provider
|
|
47
47
|
as `openrouter`. It does not add that OpenRouter-specific header for
|
|
48
48
|
non-OpenRouter providers; direct provider endpoints retain their provider-native
|
|
@@ -286,19 +286,33 @@ whether a header was already present or added, and provider-identity changes
|
|
|
286
286
|
(`glm_provider_changed`). They do not record the header value.
|
|
287
287
|
|
|
288
288
|
|
|
289
|
-
## MiMo
|
|
289
|
+
## MiMo V2.6 and later
|
|
290
290
|
|
|
291
291
|
### Policy: prefix stability + OpenRouter session affinity
|
|
292
292
|
|
|
293
|
-
MiMo-V2.6 is Xiaomi's current model family.
|
|
294
|
-
|
|
293
|
+
MiMo-V2.6 is Xiaomi's current model family. Since v0.4.5 the plugin separates
|
|
294
|
+
three concerns:
|
|
295
|
+
|
|
296
|
+
* **Family baseline** — the implicit-cache baseline plus cached-token telemetry,
|
|
297
|
+
provider-change/prefix diagnostics, and OpenRouter session affinity. This
|
|
298
|
+
applies to the documented V2.6 Flash and Pro identifiers, the
|
|
299
|
+
`mimo-v2.6-pro-ultraspeed` mode id, and any future MiMo generation after V2.6.
|
|
300
|
+
* **Validated overlay** — the `<env>` relocation described below, registered only
|
|
301
|
+
for MiMo V2.6 Flash/Pro.
|
|
302
|
+
* **Transport affinity** — OpenRouter `x-session-id`, gated on the actual
|
|
303
|
+
`openrouter` provider identity.
|
|
304
|
+
|
|
305
|
+
The documented V2.6 identifiers are:
|
|
295
306
|
|
|
296
307
|
* `xiaomi/mimo-v2.6-flash` / `mimo-v2.6-flash`
|
|
297
308
|
* `xiaomi/mimo-v2.6-pro` / `mimo-v2.6-pro`
|
|
309
|
+
* `xiaomi/mimo-v2.6-pro-ultraspeed` / `mimo-v2.6-pro-ultraspeed`
|
|
298
310
|
|
|
299
311
|
Detection also tolerates `provider/model` shapes where `api.id` contains those
|
|
300
|
-
slugs.
|
|
301
|
-
|
|
312
|
+
slugs. Future generations after V2.6 (for example `mimo-v2.7-*`) resolve to the
|
|
313
|
+
family baseline so a new model remains usable even when its exact id is unknown.
|
|
314
|
+
`mimo-v2.5`, `mimo-v2.5-pro`, `mimo-v2`, and undocumented V2.6 variants such as
|
|
315
|
+
`mimo-v2.6-flashx` remain neutral.
|
|
302
316
|
|
|
303
317
|
### Implicit context caching
|
|
304
318
|
|
|
@@ -313,9 +327,9 @@ Implicit caching is the default assumption.
|
|
|
313
327
|
|
|
314
328
|
### Environment-block stabilization
|
|
315
329
|
|
|
316
|
-
MiMo
|
|
317
|
-
identifiable volatile `<env>` block is relocated to the **tail** of
|
|
318
|
-
system string. Contents are preserved byte-for-byte; only position changes. This
|
|
330
|
+
MiMo V2.6 Flash/Pro use the same narrow, content-preserving transformation as
|
|
331
|
+
GLM-5.3: the identifiable volatile `<env>` block is relocated to the **tail** of
|
|
332
|
+
the single system string. Contents are preserved byte-for-byte; only position changes. This
|
|
319
333
|
keeps the large reusable prefix stable when only the environment/date changes.
|
|
320
334
|
|
|
321
335
|
The transformation is applied only when:
|
|
@@ -349,12 +363,13 @@ Explicit telemetry events:
|
|
|
349
363
|
|
|
350
364
|
### OpenRouter session affinity
|
|
351
365
|
|
|
352
|
-
For MiMo
|
|
353
|
-
CacheEngine adds its existing deterministic, session-scoped
|
|
354
|
-
request header. If a case-insensitive `x-session-id` already
|
|
355
|
-
plugin headers, CacheEngine preserves it and does not replace
|
|
356
|
-
uses both the MiMo
|
|
357
|
-
slug on another endpoint is not enough.
|
|
366
|
+
For MiMo V2.6-and-later requests whose actual OpenCode provider identity is
|
|
367
|
+
`openrouter`, CacheEngine adds its existing deterministic, session-scoped
|
|
368
|
+
`x-session-id` request header. If a case-insensitive `x-session-id` already
|
|
369
|
+
exists in model or plugin headers, CacheEngine preserves it and does not replace
|
|
370
|
+
it. Eligibility uses both the MiMo V2.6-and-later family and the actual provider
|
|
371
|
+
identity; a matching model slug on another endpoint is not enough. This is
|
|
372
|
+
transport affinity, separate from the V2.6 Flash/Pro `<env>` overlay.
|
|
358
373
|
|
|
359
374
|
For Xiaomi's direct endpoint and every other non-OpenRouter provider, CacheEngine
|
|
360
375
|
does not add its OpenRouter-specific `x-session-id`. Direct provider endpoints
|
|
@@ -435,7 +450,7 @@ and are reported diagnostically; the message content is left untouched.
|
|
|
435
450
|
| DeepSeek | `deepseek` (V4-and-later family + passive fallback) | No | No | None | provider `cache.read` / `cache.write` |
|
|
436
451
|
| GPT-5.6 and later | version boundary `gpt-<major>[.<minor>] ≥ 5.6` on OpenAI-ish endpoints (includes GPT-6) | No | Yes: `prompt_cache_key` + options | None | provider cache tokens |
|
|
437
452
|
| GLM-5.3 and later | `glm-5.3+` | Yes, narrowly (`<env>` tail) on GLM-5.3 only | No provider cache key | `x-session-id` on OpenRouter only | provider cache tokens (GLM ratio) |
|
|
438
|
-
| MiMo
|
|
453
|
+
| MiMo V2.6 and later | `mimo-v2.6+` (family) | Yes, narrowly (`<env>` tail) on V2.6 Flash/Pro only | No: implicit caching only | `x-session-id` on OpenRouter only | `cached_tokens / prompt_tokens` |
|
|
439
454
|
|
|
440
455
|
`x-session-id` is an HTTP affinity header, not a provider cache key or
|
|
441
456
|
cache-control field. Non-OpenRouter endpoints do not receive CacheEngine's
|
|
@@ -947,14 +962,15 @@ neutral
|
|
|
947
962
|
The model detector recognizes:
|
|
948
963
|
|
|
949
964
|
* DeepSeek model/provider identifiers
|
|
950
|
-
* GPT-5.6 variants
|
|
951
|
-
* GLM-5.3 variants
|
|
952
|
-
* MiMo
|
|
965
|
+
* GPT-5.6-and-later variants
|
|
966
|
+
* GLM-5.3-and-later variants
|
|
967
|
+
* MiMo V2.6-and-later family (`mimo-v2.6-flash`, `mimo-v2.6-pro`, `mimo-v2.6-pro-ultraspeed`, ...)
|
|
953
968
|
|
|
954
969
|
The GPT-5.6-and-later family has an additional OpenAI/Azure-context check, so a string containing a qualifying GPT version (for example `gpt-5.6` or `gpt-6`) does not automatically cause GPT-specific fields to be sent to an unrelated endpoint.
|
|
955
970
|
|
|
956
|
-
MiMo detection
|
|
957
|
-
`mimo-v2.5-pro`,
|
|
971
|
+
MiMo detection keeps the documented V2.6 ids and covers future generations after
|
|
972
|
+
V2.6; it excludes `mimo-v2.5`, `mimo-v2.5-pro`, `mimo-v2`, and undocumented V2.6
|
|
973
|
+
variants such as `mimo-v2.6-flashx`.
|
|
958
974
|
|
|
959
975
|
Unknown models use the neutral policy.
|
|
960
976
|
|
|
@@ -1053,7 +1069,7 @@ returns the runtime-facing descriptor the hooks consume: the legacy policy
|
|
|
1053
1069
|
string plus explicit capability flags.
|
|
1054
1070
|
|
|
1055
1071
|
Only registry entries marked `legacy` enable runtime behavior; documented but
|
|
1056
|
-
non-legacy
|
|
1072
|
+
non-legacy aliases (for example `gpt-daybreak-blue-latest`) and all unknown
|
|
1057
1073
|
models resolve to a neutral runtime. A newer or unknown model therefore never
|
|
1058
1074
|
inherits a current model's mutation unless the registry explicitly registers it.
|
|
1059
1075
|
The GPT family is a documented exception in the sense that its boundary is
|
|
@@ -1288,7 +1304,7 @@ release, use:
|
|
|
1288
1304
|
```json
|
|
1289
1305
|
{
|
|
1290
1306
|
"plugin": [
|
|
1291
|
-
"opencode-cache-engine@0.4.
|
|
1307
|
+
"opencode-cache-engine@0.4.5"
|
|
1292
1308
|
]
|
|
1293
1309
|
}
|
|
1294
1310
|
```
|
|
@@ -1391,14 +1407,14 @@ xiaomi/mimo-v2.6-flash
|
|
|
1391
1407
|
xiaomi/mimo-v2.6-pro
|
|
1392
1408
|
```
|
|
1393
1409
|
|
|
1394
|
-
`mimo-v2.5`, `mimo-v2.5-pro`,
|
|
1395
|
-
not matched.
|
|
1410
|
+
`mimo-v2.5`, `mimo-v2.5-pro`, `mimo-v2`, and undocumented V2.6 variants such as
|
|
1411
|
+
`mimo-v2.6-flashx` are intentionally not matched.
|
|
1396
1412
|
|
|
1397
1413
|
---
|
|
1398
1414
|
|
|
1399
1415
|
## OpenRouter affinity header is not added
|
|
1400
1416
|
|
|
1401
|
-
CacheEngine adds its `x-session-id` only for a detected MiMo
|
|
1417
|
+
CacheEngine adds its `x-session-id` only for a detected MiMo V2.6-and-later or GLM-5.3-and-later
|
|
1402
1418
|
request when the actual OpenCode `providerID` is exactly `openrouter`. A direct
|
|
1403
1419
|
provider route or missing provider identity is bypassed. If a case-insensitive
|
|
1404
1420
|
`x-session-id` is already present in model or plugin headers, it is preserved
|
|
@@ -1429,10 +1445,10 @@ A telemetry failure is intentionally swallowed so it does not break model execut
|
|
|
1429
1445
|
The current implementation is intentionally conservative:
|
|
1430
1446
|
|
|
1431
1447
|
```text
|
|
1432
|
-
DeepSeek
|
|
1433
|
-
GPT-5.6
|
|
1434
|
-
GLM-5.3
|
|
1435
|
-
MiMo
|
|
1448
|
+
DeepSeek -> preserve and measure
|
|
1449
|
+
GPT-5.6+ -> documented cache key/options; user/harness controls the 272K pricing boundary
|
|
1450
|
+
GLM-5.3+ -> family baseline; GLM-5.3 only: preserve-content <env> relocation + OpenRouter affinity header
|
|
1451
|
+
MiMo V2.6+ -> family baseline; V2.6 Flash/Pro only: preserve-content <env> relocation (+ OpenRouter affinity header)
|
|
1436
1452
|
```
|
|
1437
1453
|
|
|
1438
1454
|
That separation is the core design of the project.
|
|
@@ -75,10 +75,10 @@ Detection consequences worth stating explicitly:
|
|
|
75
75
|
matched → neutral. **[O]**
|
|
76
76
|
- `deepseek-v5` (or any future `*deepseek*` id) matches the passive DeepSeek
|
|
77
77
|
branch because the regex is a bare substring test. **[O]**
|
|
78
|
-
- `mimo-v2.6-pro-ultraspeed` is
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
78
|
+
- `mimo-v2.6-pro-ultraspeed` is matched by its own explicit entry since v0.4.5
|
|
79
|
+
(MiMo family baseline, no `<env>` overlay). **[O]**
|
|
80
|
+
- Undocumented V2.6 variants such as `mimo-v2.6-flashx` remain neutral, and
|
|
81
|
+
`mimo-v2.5*` and `glm-5.2`/`glm-4.x` are neutral. **[O]**
|
|
82
82
|
|
|
83
83
|
---
|
|
84
84
|
|
|
@@ -292,8 +292,8 @@ made here); **hold** = do not inherit without first-party evidence.
|
|
|
292
292
|
| Z.AI | 5.2 and earlier negative controls: `glm-5.2`, `glm-5.1`, `glm-5`, `glm-4.7`, `glm-4.6`, `glm-4.5`, `glm-4-32b-*` | Cacheable (except `glm-4-32b-0414-128k`), different cached-input pricing; no cache-semantics difference documented | neutral | hold | n/a | High | Z.AI *Pricing*; *Chat Completion* (enum) | 2026-09-26 |
|
|
293
293
|
| Xiaomi | MiMo V2.6 Flash: `mimo-v2.6-flash` (OR `xiaomi/mimo-v2.6-flash`) | Provider-managed implicit caching; `cached_tokens`; no documented min/TTL/key/prefix rules | MiMo policy: `<env>` relocation; provider-change telemetry; OpenRouter `x-session-id` | keep scoped as exact-model overlay | env relocation unsupported by docs → treat as overlay | Medium | MiMo *Models*; *Pricing*; *openai-api* | 2026-09-26 |
|
|
294
294
|
| Xiaomi | MiMo V2.6 Pro: `mimo-v2.6-pro` (OR `xiaomi/mimo-v2.6-pro`) | Same documented per-model implicit caching; per-model pricing | MiMo policy (same as Flash) | keep | none documented | Medium | MiMo *Models*; *Pricing* | 2026-09-26 |
|
|
295
|
-
| Xiaomi | MiMo V2.6 Pro UltraSpeed: `mimo-v2.6-pro-ultraspeed` (OR `xiaomi/mimo-v2.6-pro-ultraspeed`) | Documented as a Pro **mode**, same V2.6 series; "Context Caching" listed; no documented mechanism difference from Pro |
|
|
296
|
-
| Xiaomi | later MiMo generations: none documented beyond V2.6; V2.5 deprecates 2026-10-21 | Not documented
|
|
295
|
+
| Xiaomi | MiMo V2.6 Pro UltraSpeed: `mimo-v2.6-pro-ultraspeed` (OR `xiaomi/mimo-v2.6-pro-ultraspeed`) | Documented as a Pro **mode**, same V2.6 series; "Context Caching" listed; no documented mechanism difference from Pro | MiMo family baseline only (cached-token telemetry, provider-change/prefix diagnostics, OpenRouter affinity); **no** `<env>` overlay (v0.4.5) | family baseline; overlay stays Flash/Pro-explicit | none — baseline only | Medium | MiMo *news/latest/v2-6*; *Models*; *Pricing* | 2026-09-27 |
|
|
296
|
+
| Xiaomi | later MiMo generations: none documented beyond V2.6; V2.5 deprecates 2026-10-21 | Not documented; no inheritance rule | Passive family baseline for any future >V2.6 id (v0.4.5); no `<env>` overlay | keep passive, baseline only | none | High (no later gens documented) | MiMo *Models*; *updates/model* | 2026-09-27 |
|
|
297
297
|
| Xiaomi | V2.5 negative control: `mimo-v2.5`, `mimo-v2.5-pro` | Documented as deprecated 2026-10-21; cache capability listed; no V2.6 policy inheritance claimed | neutral | hold | n/a | High | MiMo *Models*; *news/latest/v2-6* | 2026-09-26 |
|
|
298
298
|
|
|
299
299
|
---
|
|
@@ -323,9 +323,8 @@ a newer model inherits an older policy. They must not be resolved by guessing.
|
|
|
323
323
|
undocumented.
|
|
324
324
|
9. **Xiaomi V2.6 Pro UltraSpeed cache mechanism.** Documented as the same V2.6
|
|
325
325
|
series and a Pro mode, but no first-party statement proves identical cache
|
|
326
|
-
controls to Pro/Flash.
|
|
327
|
-
|
|
328
|
-
rather than a documented fact.
|
|
326
|
+
controls to Pro/Flash. v0.4.5 resolves this as a CacheEngine scope decision:
|
|
327
|
+
UltraSpeed gets the family **baseline only** (no `<env>` overlay).
|
|
329
328
|
10. **MiMo on OpenRouter.** OpenRouter's Prompt Caching page documents no
|
|
330
329
|
MiMo-specific cache section; only generic sticky-routing behavior applies.
|
|
331
330
|
11. **OpenAI Chat Completions usage-field naming** (`prompt_tokens_details` vs
|
|
@@ -405,3 +404,27 @@ a newer model inherits an older policy. They must not be resolved by guessing.
|
|
|
405
404
|
- Evidence caveat: because no later GLM generation is documented, the
|
|
406
405
|
"GLM-5.3 and later" boundary is a CacheEngine inference about a passive
|
|
407
406
|
baseline, not a Z.AI contract; it is safe because it introduces no mutation.
|
|
407
|
+
|
|
408
|
+
### Follow-up: v0.4.5 MiMo V2.6+ baseline vs the validated MiMo overlay
|
|
409
|
+
|
|
410
|
+
- Xiaomi MiMo docs were re-verified on **2026-09-27**. The V2.6 series is Pro +
|
|
411
|
+
Flash, with UltraSpeed documented as a Pro **mode** exposed as
|
|
412
|
+
`mimo-v2.6-pro-ultraspeed`. No generation newer than V2.6 is documented, and
|
|
413
|
+
no generational-inheritance rule is published. Caching is provider-managed
|
|
414
|
+
implicit with no cache-control field in any compat schema; usage fields are
|
|
415
|
+
per-protocol `cached_tokens`/`cache_read_input_tokens`. V2.5 deprecates
|
|
416
|
+
2026-10-21.
|
|
417
|
+
- The `<env>` relocation has **no first-party basis** — it is a CacheEngine
|
|
418
|
+
overlay. v0.4.5 therefore separates:
|
|
419
|
+
- **Family baseline** (documented V2.6 Flash/Pro, the UltraSpeed mode entry,
|
|
420
|
+
and any future >V2.6 id via `isMimoAfterV26`): cached-token telemetry,
|
|
421
|
+
provider-change/prefix diagnostics, OpenRouter `x-session-id`. No prompt
|
|
422
|
+
rewrite.
|
|
423
|
+
- **Validated overlay**: the `<env>` relocation stays registered only on the
|
|
424
|
+
V2.6 Flash/Pro entry.
|
|
425
|
+
- UltraSpeed moves from neutral to the family baseline (no overlay). V2.5 and
|
|
426
|
+
earlier stay neutral; undocumented V2.6 variants such as `mimo-v2.6-flashx`
|
|
427
|
+
also stay neutral (narrow detection preserved).
|
|
428
|
+
- No MiMo cache-control field is invented. Evidence caveat: since no >V2.6
|
|
429
|
+
generation is documented, future coverage is a CacheEngine inference about a
|
|
430
|
+
passive baseline (safe: no mutation), not a Xiaomi contract.
|
package/package.json
CHANGED
|
@@ -121,6 +121,30 @@ export function isGlm53OrLater(slug) {
|
|
|
121
121
|
return false
|
|
122
122
|
}
|
|
123
123
|
|
|
124
|
+
// MiMo generations strictly newer than V2.6 (docs/cache-policy-inventory.md §4;
|
|
125
|
+
// Xiaomi docs re-verified 2026-09-27). The documented V2.6 ids (Flash/Pro and
|
|
126
|
+
// the Pro UltraSpeed mode) are matched by their explicit entries; this predicate
|
|
127
|
+
// covers a future V2.7+/V3+ generation that CacheEngine has never seen, granting
|
|
128
|
+
// only the passive baseline (telemetry + transport) and never the `<env>`
|
|
129
|
+
// relocation overlay, so it is safe by construction. V2.5 and earlier stay
|
|
130
|
+
// neutral.
|
|
131
|
+
//
|
|
132
|
+
// It intentionally does NOT match the existing V2.6 literal, so undocumented
|
|
133
|
+
// V2.6 variants (for example `mimo-v2.6-flashx`) stay neutral per the narrow
|
|
134
|
+
// MiMo detection rule.
|
|
135
|
+
export function isMimoAfterV26(slug) {
|
|
136
|
+
const text = String(slug ?? "").toLowerCase()
|
|
137
|
+
const re = /mimo-v(\d+)(?:\.(\d+))?(?![\d.])/g
|
|
138
|
+
let m
|
|
139
|
+
while ((m = re.exec(text)) !== null) {
|
|
140
|
+
const major = Number(m[1])
|
|
141
|
+
const minor = m[2] === undefined ? 0 : Number(m[2])
|
|
142
|
+
if (major > 2) return true
|
|
143
|
+
if (major === 2 && minor > 6) return true
|
|
144
|
+
}
|
|
145
|
+
return false
|
|
146
|
+
}
|
|
147
|
+
|
|
124
148
|
// Candidate ids for exact/alias lookup. Includes the raw apiID/modelID, the
|
|
125
149
|
// lower-cased forms, and a single stripped transport/vendor prefix
|
|
126
150
|
// (e.g. "openai/gpt-5.6-luna" -> "gpt-5.6-luna", "xiaomi/mimo-v2.6-flash" ->
|
|
@@ -409,14 +433,42 @@ export const POLICY_REGISTRY = [
|
|
|
409
433
|
id: "xiaomi.mimo-v2.6-pro-ultraspeed",
|
|
410
434
|
creator: "xiaomi",
|
|
411
435
|
family: "mimo-v2.6",
|
|
412
|
-
kind: "
|
|
436
|
+
kind: "family",
|
|
437
|
+
pattern: /mimo-v2\.6-pro-ultraspeed/i,
|
|
413
438
|
exactIds: ["mimo-v2.6-pro-ultraspeed"],
|
|
414
439
|
baseline: "xiaomi.implicit-cache",
|
|
415
440
|
overlays: [],
|
|
416
|
-
legacy:
|
|
417
|
-
runtime: rt("
|
|
418
|
-
|
|
419
|
-
|
|
441
|
+
legacy: true,
|
|
442
|
+
runtime: rt("mimo26", {
|
|
443
|
+
cacheRatio: "mimo",
|
|
444
|
+
providerChange: "mimo",
|
|
445
|
+
prefixDiagnostics: true,
|
|
446
|
+
openRouterAffinity: true,
|
|
447
|
+
}),
|
|
448
|
+
policyStatus: "documented-series-member-baseline-only",
|
|
449
|
+
note: "v0.4.5: documented as a Pro mode in the same V2.6 series. It gets the MiMo family baseline (cached-token telemetry, provider-change/prefix diagnostics, OpenRouter affinity) but NOT the validated `<env>` relocation overlay.",
|
|
450
|
+
inventoryRef: "§4 Xiaomi MiMo",
|
|
451
|
+
},
|
|
452
|
+
{
|
|
453
|
+
// v0.4.5: "MiMo V2.6 and later" family baseline. A future 2.6+ model gets
|
|
454
|
+
// the passive baseline and its non-mutating diagnostics/transport, but never
|
|
455
|
+
// the `<env>` overlay, which stays explicit to the validated Flash/Pro entry.
|
|
456
|
+
id: "xiaomi.mimo-v2.6-plus",
|
|
457
|
+
creator: "xiaomi",
|
|
458
|
+
family: "mimo-v2.6",
|
|
459
|
+
kind: "family",
|
|
460
|
+
predicate: isMimoAfterV26,
|
|
461
|
+
baseline: "xiaomi.implicit-cache",
|
|
462
|
+
overlays: [],
|
|
463
|
+
legacy: true,
|
|
464
|
+
runtime: rt("mimo26", {
|
|
465
|
+
cacheRatio: "mimo",
|
|
466
|
+
providerChange: "mimo",
|
|
467
|
+
prefixDiagnostics: true,
|
|
468
|
+
openRouterAffinity: true,
|
|
469
|
+
}),
|
|
470
|
+
boundary: "MiMo V2.6 and later",
|
|
471
|
+
note: "Xiaomi documents implicit caching with no cache-control field and no generational-inheritance rule; the `<env>` relocation is a CacheEngine overlay with no first-party basis and is not inherited.",
|
|
420
472
|
inventoryRef: "§4 Xiaomi MiMo",
|
|
421
473
|
},
|
|
422
474
|
{
|
|
@@ -56,6 +56,7 @@ import {
|
|
|
56
56
|
isDeepseekV4OrLater,
|
|
57
57
|
isGlm53OrLater,
|
|
58
58
|
isGpt56OrLater,
|
|
59
|
+
isMimoAfterV26,
|
|
59
60
|
resolveLegacyFamily,
|
|
60
61
|
resolvePolicy,
|
|
61
62
|
resolveRuntimePolicy,
|
|
@@ -325,11 +326,13 @@ test("MiMo V2.6 Flash/Pro match MiMo policy (openrouter + direct)", () => {
|
|
|
325
326
|
)
|
|
326
327
|
})
|
|
327
328
|
|
|
328
|
-
test("MiMo V2.5
|
|
329
|
+
test("MiMo V2.5 stays neutral; V2.6 Pro UltraSpeed now resolves (v0.4.5)", () => {
|
|
329
330
|
assert.equal(detectPolicy(M("openrouter", "xiaomi/mimo-v2.5")), POLICY_NEUTRAL)
|
|
330
331
|
assert.equal(detectPolicy(M("openrouter", "xiaomi/mimo-v2.5-pro")), POLICY_NEUTRAL)
|
|
331
332
|
assert.equal(detectPolicy(M("xiaomi", "mimo-v2.5")), POLICY_NEUTRAL)
|
|
332
|
-
|
|
333
|
+
// v0.4.5: UltraSpeed is a documented V2.6 series member (baseline only).
|
|
334
|
+
assert.equal(detectPolicy(M("xiaomi", "mimo-v2.6-pro-ultraspeed")), POLICY_MIMO26)
|
|
335
|
+
// Undocumented V2.6 variants remain neutral (narrow detection preserved).
|
|
333
336
|
assert.equal(detectPolicy(M("xiaomi", "mimo-v2.6-flashx")), POLICY_NEUTRAL)
|
|
334
337
|
})
|
|
335
338
|
|
|
@@ -1448,7 +1451,7 @@ test("resolvePolicy: MiMo V2.6 Flash/Pro carry the overlay; Pro UltraSpeed is an
|
|
|
1448
1451
|
assert.equal(ultraspeed.matchType, "exact")
|
|
1449
1452
|
assert.deepEqual(overlayIds(ultraspeed), [])
|
|
1450
1453
|
const uEntry = POLICY_REGISTRY.find((e) => e.id === "xiaomi.mimo-v2.6-pro-ultraspeed")
|
|
1451
|
-
assert.equal(uEntry.policyStatus, "documented-series-member-
|
|
1454
|
+
assert.equal(uEntry.policyStatus, "documented-series-member-baseline-only")
|
|
1452
1455
|
|
|
1453
1456
|
const v25 = resolvePolicy(M("xiaomi", "mimo-v2.5"))
|
|
1454
1457
|
assert.equal(v25.family, "neutral")
|
|
@@ -1656,7 +1659,10 @@ async function runPolicyMigrationProbe() {
|
|
|
1656
1659
|
{ name: "glm-5.2", model: { providerID: "zai", id: "glm-5.2", api: { id: "glm-5.2" } }, expect: { policy: "neutral", env: false, gpt: false, header: false } },
|
|
1657
1660
|
{ name: "mimo-v2.6-flash-direct", model: { providerID: "xiaomi", id: "mimo-v2.6-flash", api: { id: "mimo-v2.6-flash" } }, expect: { policy: "mimo26", env: true, gpt: false, header: false } },
|
|
1658
1661
|
{ name: "mimo-v2.6-pro-openrouter", model: { providerID: "openrouter", id: "xiaomi/mimo-v2.6-pro", api: { id: "xiaomi/mimo-v2.6-pro" } }, expect: { policy: "mimo26", env: true, gpt: false, header: true } },
|
|
1659
|
-
{ name: "mimo-v2.6-pro-ultraspeed", model: { providerID: "xiaomi", id: "mimo-v2.6-pro-ultraspeed", api: { id: "mimo-v2.6-pro-ultraspeed" } }, expect: { policy: "
|
|
1662
|
+
{ name: "mimo-v2.6-pro-ultraspeed", model: { providerID: "xiaomi", id: "mimo-v2.6-pro-ultraspeed", api: { id: "mimo-v2.6-pro-ultraspeed" } }, expect: { policy: "mimo26", env: false, gpt: false, header: false } },
|
|
1663
|
+
{ name: "mimo-v2.7-future", model: { providerID: "xiaomi", id: "mimo-v2.7-flash", api: { id: "mimo-v2.7-flash" } }, expect: { policy: "mimo26", env: false, gpt: false, header: false } },
|
|
1664
|
+
{ name: "mimo-v2.7-openrouter", model: { providerID: "openrouter", id: "xiaomi/mimo-v2.7-flash", api: { id: "xiaomi/mimo-v2.7-flash" } }, expect: { policy: "mimo26", env: false, gpt: false, header: true } },
|
|
1665
|
+
{ name: "mimo-v2.6-pro-ultraspeed-openrouter", model: { providerID: "openrouter", id: "xiaomi/mimo-v2.6-pro-ultraspeed", api: { id: "xiaomi/mimo-v2.6-pro-ultraspeed" } }, expect: { policy: "mimo26", env: false, gpt: false, header: true } },
|
|
1660
1666
|
{ name: "mimo-v2.5", model: { providerID: "xiaomi", id: "mimo-v2.5", api: { id: "mimo-v2.5" } }, expect: { policy: "neutral", env: false, gpt: false, header: false } },
|
|
1661
1667
|
{ name: "unknown-provider", model: { providerID: "mystery-provider", id: "xiaomi/mimo-v2.6-flash", api: { id: "xiaomi/mimo-v2.6-flash" } }, expect: { policy: "mimo26", env: true, gpt: false, header: false } },
|
|
1662
1668
|
{ name: "unknown-openrouter", model: { providerID: "openrouter", id: "acme/mystery-9", api: { id: "acme/mystery-9" } }, expect: { policy: "neutral", env: false, gpt: false, header: false } },
|
|
@@ -2010,3 +2016,102 @@ test("v0.4.4: GLM OpenRouter affinity is transport-gated for later GLM too", asy
|
|
|
2010
2016
|
assert.equal(or.existingHeadersPreserved, true)
|
|
2011
2017
|
assert.equal(direct.existingHeadersPreserved, true)
|
|
2012
2018
|
})
|
|
2019
|
+
|
|
2020
|
+
// ===========================================================================
|
|
2021
|
+
// v0.4.5 MiMo V2.6+ family baseline vs the validated MiMo overlay
|
|
2022
|
+
//
|
|
2023
|
+
// Source: Xiaomi MiMo docs re-verified 2026-09-27
|
|
2024
|
+
// (docs/cache-policy-inventory.md §4). Caching is provider-managed/implicit with
|
|
2025
|
+
// no cache-control field; the `<env>` relocation is a CacheEngine overlay with
|
|
2026
|
+
// no first-party basis; V2.5 deprecates 2026-10-21. No V2.7+/inheritance rule is
|
|
2027
|
+
// documented, so future coverage is a safe passive baseline only.
|
|
2028
|
+
// ===========================================================================
|
|
2029
|
+
|
|
2030
|
+
test("v0.4.5: isMimoAfterV26 matches generations strictly after V2.6", () => {
|
|
2031
|
+
const inFamily = ["mimo-v2.7-flash", "mimo-v2.7", "mimo-v2.8-pro", "mimo-v3", "mimo-v3.1-flash", "xiaomi/mimo-v2.7-flash"]
|
|
2032
|
+
for (const id of inFamily) assert.equal(isMimoAfterV26(id), true, `${id} is after V2.6`)
|
|
2033
|
+
const outOfFamily = ["mimo-v2.6-flash", "mimo-v2.6-pro", "mimo-v2.6-pro-ultraspeed", "mimo-v2.6-flashx", "mimo-v2.5", "mimo-v2.5-pro", "mimo-v2-flash", ""]
|
|
2034
|
+
for (const id of outOfFamily) assert.equal(isMimoAfterV26(id), false, `${id} is not after V2.6`)
|
|
2035
|
+
})
|
|
2036
|
+
|
|
2037
|
+
test("v0.4.5: Flash/Pro keep the overlay; UltraSpeed and later get the baseline only", () => {
|
|
2038
|
+
const flash = resolvePolicy(M("xiaomi", "mimo-v2.6-flash"))
|
|
2039
|
+
assert.equal(flash.family, "mimo-v2.6")
|
|
2040
|
+
assert.equal(baseId(flash), "xiaomi.implicit-cache")
|
|
2041
|
+
assert.deepEqual(overlayIds(flash), ["mimo26.env-relocation"])
|
|
2042
|
+
assert.deepEqual(overlayIds(resolvePolicy(M("xiaomi", "mimo-v2.6-pro"))), ["mimo26.env-relocation"])
|
|
2043
|
+
|
|
2044
|
+
for (const id of ["mimo-v2.6-pro-ultraspeed", "mimo-v2.7-flash"]) {
|
|
2045
|
+
const r = resolvePolicy(M("xiaomi", id))
|
|
2046
|
+
assert.equal(r.family, "mimo-v2.6", `${id}: family`)
|
|
2047
|
+
assert.equal(baseId(r), "xiaomi.implicit-cache", `${id}: same baseline`)
|
|
2048
|
+
assert.deepEqual(overlayIds(r), [], `${id}: no overlay`)
|
|
2049
|
+
const c = resolveRuntimePolicy(M("xiaomi", id))
|
|
2050
|
+
assert.equal(c.policy, "mimo26", `${id}: policy`)
|
|
2051
|
+
assert.equal(c.envRelocation, null, `${id}: no prompt rewrite`)
|
|
2052
|
+
assert.equal(c.cacheRatio, "mimo", `${id}: cached-token ratio`)
|
|
2053
|
+
assert.equal(c.providerChange, "mimo", `${id}: provider diagnostics`)
|
|
2054
|
+
assert.equal(c.openRouterAffinity, true, `${id}: affinity capability`)
|
|
2055
|
+
assert.equal(c.gptCacheMetadata, false, `${id}: no leak`)
|
|
2056
|
+
}
|
|
2057
|
+
|
|
2058
|
+
// Same baseline object family for the overlay and non-overlay members.
|
|
2059
|
+
assert.equal(baseId(resolvePolicy(M("xiaomi", "mimo-v2.7-flash"))), baseId(flash))
|
|
2060
|
+
})
|
|
2061
|
+
|
|
2062
|
+
test("v0.4.5: MiMo V2.5 and earlier stay neutral", () => {
|
|
2063
|
+
for (const id of ["mimo-v2.5", "mimo-v2.5-pro", "mimo-v2-flash", "mimo-v2"]) {
|
|
2064
|
+
const r = resolvePolicy(M("xiaomi", id))
|
|
2065
|
+
assert.equal(r.family, "neutral", `${id}: neutral`)
|
|
2066
|
+
assert.deepEqual(overlayIds(r), [], `${id}: no overlay`)
|
|
2067
|
+
assert.equal(resolveRuntimePolicy(M("xiaomi", id)).policy, "neutral", `${id}: neutral runtime`)
|
|
2068
|
+
}
|
|
2069
|
+
})
|
|
2070
|
+
|
|
2071
|
+
test("v0.4.5: legacy detectPolicy follows the MiMo V2.6+ boundary", () => {
|
|
2072
|
+
assert.equal(detectPolicy(M("xiaomi", "mimo-v2.6-flash")), POLICY_MIMO26)
|
|
2073
|
+
assert.equal(detectPolicy(M("xiaomi", "mimo-v2.6-pro-ultraspeed")), POLICY_MIMO26)
|
|
2074
|
+
assert.equal(detectPolicy(M("xiaomi", "mimo-v2.7-flash")), POLICY_MIMO26)
|
|
2075
|
+
assert.equal(detectPolicy(M("xiaomi", "mimo-v2.5")), POLICY_NEUTRAL)
|
|
2076
|
+
assert.equal(detectPolicy(M("xiaomi", "mimo-v2.6-flashx")), POLICY_NEUTRAL)
|
|
2077
|
+
})
|
|
2078
|
+
|
|
2079
|
+
test("v0.4.5: <env> absent is a no-op for MiMo transforms", () => {
|
|
2080
|
+
const plain = "Stable MiMo instructions.\nNo environment block."
|
|
2081
|
+
const r = relocateVolatileEnvBlock(plain)
|
|
2082
|
+
assert.equal(r.changed, false)
|
|
2083
|
+
assert.equal(r.text, plain)
|
|
2084
|
+
})
|
|
2085
|
+
|
|
2086
|
+
test("v0.4.5: later MiMo inherits the baseline but never the <env> overlay (runtime)", async () => {
|
|
2087
|
+
const { results } = await policyMigrationResults()
|
|
2088
|
+
const flash = results.find((r) => r.name === "mimo-v2.6-flash-direct")
|
|
2089
|
+
const ultra = results.find((r) => r.name === "mimo-v2.6-pro-ultraspeed")
|
|
2090
|
+
const future = results.find((r) => r.name === "mimo-v2.7-future")
|
|
2091
|
+
assert.ok(flash && ultra && future)
|
|
2092
|
+
// Identical system text with a valid <env> block present in every case.
|
|
2093
|
+
assert.equal(flash.systemRelocated, true) // validated Flash overlay fires
|
|
2094
|
+
assert.equal(ultra.systemRelocated, false) // UltraSpeed: baseline only
|
|
2095
|
+
assert.equal(future.systemRelocated, false) // future model: baseline only
|
|
2096
|
+
assert.equal(ultra.runtimePolicy, "mimo26")
|
|
2097
|
+
assert.equal(future.runtimePolicy, "mimo26")
|
|
2098
|
+
})
|
|
2099
|
+
|
|
2100
|
+
test("v0.4.5: MiMo OpenRouter affinity stays transport-gated", async () => {
|
|
2101
|
+
const { results } = await policyMigrationResults()
|
|
2102
|
+
const orFuture = results.find((r) => r.name === "mimo-v2.7-openrouter")
|
|
2103
|
+
const orUltra = results.find((r) => r.name === "mimo-v2.6-pro-ultraspeed-openrouter")
|
|
2104
|
+
const direct = results.find((r) => r.name === "mimo-v2.7-future")
|
|
2105
|
+
assert.equal(orFuture.affinityHeaderAttached, true)
|
|
2106
|
+
assert.equal(orUltra.affinityHeaderAttached, true)
|
|
2107
|
+
assert.equal(direct.affinityHeaderAttached, false)
|
|
2108
|
+
assert.equal(orFuture.systemRelocated, false) // affinity is transport, not the overlay
|
|
2109
|
+
})
|
|
2110
|
+
|
|
2111
|
+
test("v0.4.5: MiMo baseline invents no cache fields and keeps cached-token telemetry", () => {
|
|
2112
|
+
const c = resolveRuntimePolicy(M("xiaomi", "mimo-v2.7-flash"))
|
|
2113
|
+
assert.equal(c.gptCacheMetadata, false)
|
|
2114
|
+
assert.equal(c.envRelocation, null)
|
|
2115
|
+
assert.equal(c.cacheRatio, "mimo") // cachedTokens / promptTokens
|
|
2116
|
+
assert.equal(mimoHitRate(75, 100), 75)
|
|
2117
|
+
})
|