opencode-cache-engine 0.4.3 → 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 +55 -33
- package/docs/cache-policy-inventory.md +54 -10
- package/package.json +1 -1
- package/src/cache-policy-core.mjs +99 -5
- package/test/cache-engine.test.mjs +204 -4
package/README.md
CHANGED
|
@@ -31,8 +31,8 @@ The plugin currently has four cache-policy families:
|
|
|
31
31
|
* **GPT-5.6 and later** — documented cache-key/options metadata, with prompt text
|
|
32
32
|
unchanged. GPT-6 and future 5.6+/6+/7+ versions resolve through the same
|
|
33
33
|
documented boundary.
|
|
34
|
-
* **GLM-5.3** — narrow, content-preserving `<env>` relocation
|
|
35
|
-
* **MiMo
|
|
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 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
|
|
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
|
|
@@ -205,6 +205,12 @@ GLM-5.3 and MiMo-V2.6 use the only prompt-text transformation in the current
|
|
|
205
205
|
plugin: a narrow, content-preserving relocation of the identifiable `<env>`
|
|
206
206
|
block for the eligible model family.
|
|
207
207
|
|
|
208
|
+
Since v0.4.4 the GLM **family baseline** and the GLM-5.3 **overlay** are
|
|
209
|
+
separate. A resolved GLM-5.3-and-later model inherits the implicit-cache baseline
|
|
210
|
+
and the non-mutating GLM diagnostics/transport, but the `<env>` relocation below
|
|
211
|
+
is a GLM-5.3-specific overlay and is **not** inherited by a newer GLM merely
|
|
212
|
+
because its version number is higher.
|
|
213
|
+
|
|
208
214
|
The plugin identifies OpenCode's volatile `<env>` section and moves it to the **tail of the system prompt**.
|
|
209
215
|
|
|
210
216
|
Conceptually:
|
|
@@ -280,19 +286,33 @@ whether a header was already present or added, and provider-identity changes
|
|
|
280
286
|
(`glm_provider_changed`). They do not record the header value.
|
|
281
287
|
|
|
282
288
|
|
|
283
|
-
## MiMo
|
|
289
|
+
## MiMo V2.6 and later
|
|
284
290
|
|
|
285
291
|
### Policy: prefix stability + OpenRouter session affinity
|
|
286
292
|
|
|
287
|
-
MiMo-V2.6 is Xiaomi's current model family.
|
|
288
|
-
|
|
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:
|
|
289
306
|
|
|
290
307
|
* `xiaomi/mimo-v2.6-flash` / `mimo-v2.6-flash`
|
|
291
308
|
* `xiaomi/mimo-v2.6-pro` / `mimo-v2.6-pro`
|
|
309
|
+
* `xiaomi/mimo-v2.6-pro-ultraspeed` / `mimo-v2.6-pro-ultraspeed`
|
|
292
310
|
|
|
293
311
|
Detection also tolerates `provider/model` shapes where `api.id` contains those
|
|
294
|
-
slugs.
|
|
295
|
-
|
|
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.
|
|
296
316
|
|
|
297
317
|
### Implicit context caching
|
|
298
318
|
|
|
@@ -307,9 +327,9 @@ Implicit caching is the default assumption.
|
|
|
307
327
|
|
|
308
328
|
### Environment-block stabilization
|
|
309
329
|
|
|
310
|
-
MiMo
|
|
311
|
-
identifiable volatile `<env>` block is relocated to the **tail** of
|
|
312
|
-
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
|
|
313
333
|
keeps the large reusable prefix stable when only the environment/date changes.
|
|
314
334
|
|
|
315
335
|
The transformation is applied only when:
|
|
@@ -343,12 +363,13 @@ Explicit telemetry events:
|
|
|
343
363
|
|
|
344
364
|
### OpenRouter session affinity
|
|
345
365
|
|
|
346
|
-
For MiMo
|
|
347
|
-
CacheEngine adds its existing deterministic, session-scoped
|
|
348
|
-
request header. If a case-insensitive `x-session-id` already
|
|
349
|
-
plugin headers, CacheEngine preserves it and does not replace
|
|
350
|
-
uses both the MiMo
|
|
351
|
-
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.
|
|
352
373
|
|
|
353
374
|
For Xiaomi's direct endpoint and every other non-OpenRouter provider, CacheEngine
|
|
354
375
|
does not add its OpenRouter-specific `x-session-id`. Direct provider endpoints
|
|
@@ -428,8 +449,8 @@ and are reported diagnostically; the message content is left untouched.
|
|
|
428
449
|
| ------------- | --------- | ------------------- | ----------------------- | -------------------------- | -------------------- |
|
|
429
450
|
| DeepSeek | `deepseek` (V4-and-later family + passive fallback) | No | No | None | provider `cache.read` / `cache.write` |
|
|
430
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 |
|
|
431
|
-
| GLM-5.3 | `glm-5.3
|
|
432
|
-
| MiMo
|
|
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) |
|
|
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` |
|
|
433
454
|
|
|
434
455
|
`x-session-id` is an HTTP affinity header, not a provider cache key or
|
|
435
456
|
cache-control field. Non-OpenRouter endpoints do not receive CacheEngine's
|
|
@@ -941,14 +962,15 @@ neutral
|
|
|
941
962
|
The model detector recognizes:
|
|
942
963
|
|
|
943
964
|
* DeepSeek model/provider identifiers
|
|
944
|
-
* GPT-5.6 variants
|
|
945
|
-
* GLM-5.3 variants
|
|
946
|
-
* 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`, ...)
|
|
947
968
|
|
|
948
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.
|
|
949
970
|
|
|
950
|
-
MiMo detection
|
|
951
|
-
`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`.
|
|
952
974
|
|
|
953
975
|
Unknown models use the neutral policy.
|
|
954
976
|
|
|
@@ -1047,7 +1069,7 @@ returns the runtime-facing descriptor the hooks consume: the legacy policy
|
|
|
1047
1069
|
string plus explicit capability flags.
|
|
1048
1070
|
|
|
1049
1071
|
Only registry entries marked `legacy` enable runtime behavior; documented but
|
|
1050
|
-
non-legacy
|
|
1072
|
+
non-legacy aliases (for example `gpt-daybreak-blue-latest`) and all unknown
|
|
1051
1073
|
models resolve to a neutral runtime. A newer or unknown model therefore never
|
|
1052
1074
|
inherits a current model's mutation unless the registry explicitly registers it.
|
|
1053
1075
|
The GPT family is a documented exception in the sense that its boundary is
|
|
@@ -1282,7 +1304,7 @@ release, use:
|
|
|
1282
1304
|
```json
|
|
1283
1305
|
{
|
|
1284
1306
|
"plugin": [
|
|
1285
|
-
"opencode-cache-engine@0.4.
|
|
1307
|
+
"opencode-cache-engine@0.4.5"
|
|
1286
1308
|
]
|
|
1287
1309
|
}
|
|
1288
1310
|
```
|
|
@@ -1385,14 +1407,14 @@ xiaomi/mimo-v2.6-flash
|
|
|
1385
1407
|
xiaomi/mimo-v2.6-pro
|
|
1386
1408
|
```
|
|
1387
1409
|
|
|
1388
|
-
`mimo-v2.5`, `mimo-v2.5-pro`,
|
|
1389
|
-
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.
|
|
1390
1412
|
|
|
1391
1413
|
---
|
|
1392
1414
|
|
|
1393
1415
|
## OpenRouter affinity header is not added
|
|
1394
1416
|
|
|
1395
|
-
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
|
|
1396
1418
|
request when the actual OpenCode `providerID` is exactly `openrouter`. A direct
|
|
1397
1419
|
provider route or missing provider identity is bypassed. If a case-insensitive
|
|
1398
1420
|
`x-session-id` is already present in model or plugin headers, it is preserved
|
|
@@ -1423,10 +1445,10 @@ A telemetry failure is intentionally swallowed so it does not break model execut
|
|
|
1423
1445
|
The current implementation is intentionally conservative:
|
|
1424
1446
|
|
|
1425
1447
|
```text
|
|
1426
|
-
DeepSeek
|
|
1427
|
-
GPT-5.6
|
|
1428
|
-
GLM-5.3
|
|
1429
|
-
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)
|
|
1430
1452
|
```
|
|
1431
1453
|
|
|
1432
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
|
|
|
@@ -288,12 +288,12 @@ made here); **hold** = do not inherit without first-party evidence.
|
|
|
288
288
|
| DeepSeek | future-looking V4+ identifiers: `deepseek-v4.1`, `deepseek-v4`, `deepseek-v5` | Not documented as request ids (`deepseek-v4.1`/`deepseek-v4` invalid or version-string only) | Passive via the V4-and-later family predicate or the safe creator fallback (v0.4.3); no mutation | keep passive; treat as unknown-friendly | none | Medium (detection) / Low (future ids) | DeepSeek *Models & Pricing*; *Chat Completions API* | 2026-09-27 |
|
|
289
289
|
| DeepSeek | pre-V4 negative controls: `deepseek-chat`, `deepseek-reasoner` | Retired names (retired 2026-07-24); no separate V4+ cache policy claimed | Passive | hold | n/a | High | DeepSeek *Change Log*; *news260424* | 2026-09-26 |
|
|
290
290
|
| Z.AI | GLM 5.3: `glm-5.3`, `glm-5.3-flash`, `glm-5.3-flashx` | Implicit automatic caching; `cached_tokens`; stable-prompt-first guidance; no documented min/TTL/key | GLM policy: `<env>` relocation; OpenRouter `x-session-id` | keep (env relocation is an exact overlay, not a Z.AI control) | env relocation is the overlay; keep scoped to GLM-5.3 | Medium | Z.AI *Context Caching*; *Chat Completion*; *Pricing* | 2026-09-26 |
|
|
291
|
-
| Z.AI | current later GLM generations (documented): none newer than 5.3; newest below is `glm-5.2`/`glm-5.1`/`glm-5`/`glm-4.7` | Same implicit mechanism documented service-wide; cached-input price per model |
|
|
291
|
+
| Z.AI | current later GLM generations (documented): none newer than 5.3; newest below is `glm-5.2`/`glm-5.1`/`glm-5`/`glm-4.7` | Same implicit mechanism documented service-wide; cached-input price per model | GLM-5.3 family baseline via the 5.3-and-later boundary; **no** `<env>` overlay (v0.4.4) | **baseline only** — overlay stays 5.3-explicit | none documented | High (no later gens documented) | Z.AI *New Released*; *Pricing* | 2026-09-27 |
|
|
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
|
|
@@ -384,3 +383,48 @@ a newer model inherits an older policy. They must not be resolved by guessing.
|
|
|
384
383
|
- Evidence caveat: first-party pages conflict on whether `deepseek-v4-pro` still
|
|
385
384
|
routes as a distinct model in late 2026; this does not affect the passive
|
|
386
385
|
policy, which carries no mutation either way.
|
|
386
|
+
|
|
387
|
+
### Follow-up: v0.4.4 GLM-5.3-and-later baseline vs GLM-5.3 overlay
|
|
388
|
+
|
|
389
|
+
- Z.AI docs were re-verified on **2026-09-27**. GLM-5.3 is the newest documented
|
|
390
|
+
text generation (no `glm-5.4`/`glm-6`); GLM-5.3 is explicitly "the same base
|
|
391
|
+
model as GLM-5.2" with post-training differences. Caching is implicit with no
|
|
392
|
+
`cache_control`/`prompt_cache_key`/breakpoint/TTL field; `cached_tokens` is the
|
|
393
|
+
reported field. Z.AI publishes **no** generational-inheritance rule.
|
|
394
|
+
- The `<env>` relocation has **no first-party basis** — it is a CacheEngine
|
|
395
|
+
implementation overlay. v0.4.4 therefore separates the concepts:
|
|
396
|
+
- **Family baseline** (`zai.glm-5.3-plus`, predicate `glm >= 5.3`): implicit
|
|
397
|
+
caching plus the non-mutating GLM diagnostics/transport (thinking-integrity
|
|
398
|
+
telemetry, GLM cache ratio, provider-change telemetry, OpenRouter
|
|
399
|
+
`x-session-id`). No prompt rewrite.
|
|
400
|
+
- **GLM-5.3 overlay**: the `<env>` relocation stays registered only on the
|
|
401
|
+
GLM-5.3 family entry, so a later GLM does **not** inherit it.
|
|
402
|
+
- GLM-5.2 and earlier remain neutral. No new GLM cache-control field is added,
|
|
403
|
+
and GLM-5.3 behavior is unchanged.
|
|
404
|
+
- Evidence caveat: because no later GLM generation is documented, the
|
|
405
|
+
"GLM-5.3 and later" boundary is a CacheEngine inference about a passive
|
|
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
|
@@ -102,6 +102,49 @@ export function isDeepseekV4OrLater(slug) {
|
|
|
102
102
|
return false
|
|
103
103
|
}
|
|
104
104
|
|
|
105
|
+
// GLM-5.3-and-later family baseline (docs/cache-policy-inventory.md §3; Z.AI
|
|
106
|
+
// docs re-verified 2026-09-27). Z.AI publishes no generational-inheritance rule
|
|
107
|
+
// and no explicit cache control, so this is a CacheEngine inference about a
|
|
108
|
+
// passive/implicit baseline; it is safe because it grants no mutation. The
|
|
109
|
+
// GLM-5.3 `<env>` relocation is a separate, explicit overlay and is NOT granted
|
|
110
|
+
// by this predicate. GLM-5.2 and earlier stay outside this family.
|
|
111
|
+
export function isGlm53OrLater(slug) {
|
|
112
|
+
const text = String(slug ?? "").toLowerCase()
|
|
113
|
+
const re = /glm-(\d{1,3})(?:\.(\d))?(?![\d.])/g
|
|
114
|
+
let m
|
|
115
|
+
while ((m = re.exec(text)) !== null) {
|
|
116
|
+
const major = Number(m[1])
|
|
117
|
+
const minor = m[2] === undefined ? 0 : Number(m[2])
|
|
118
|
+
if (major > 5) return true
|
|
119
|
+
if (major === 5 && minor >= 3) return true
|
|
120
|
+
}
|
|
121
|
+
return false
|
|
122
|
+
}
|
|
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
|
+
|
|
105
148
|
// Candidate ids for exact/alias lookup. Includes the raw apiID/modelID, the
|
|
106
149
|
// lower-cased forms, and a single stripped transport/vendor prefix
|
|
107
150
|
// (e.g. "openai/gpt-5.6-luna" -> "gpt-5.6-luna", "xiaomi/mimo-v2.6-flash" ->
|
|
@@ -344,6 +387,29 @@ export const POLICY_REGISTRY = [
|
|
|
344
387
|
}),
|
|
345
388
|
inventoryRef: "§3 Z.AI GLM",
|
|
346
389
|
},
|
|
390
|
+
{
|
|
391
|
+
// v0.4.4: "GLM-5.3 and later" family baseline. A future 5.3+ model inherits
|
|
392
|
+
// the implicit-cache baseline and its non-mutating diagnostics/transport,
|
|
393
|
+
// but NOT the GLM-5.3-specific `<env>` relocation overlay (`overlays: []`
|
|
394
|
+
// and no `envRelocation` capability). GLM-5.2 and earlier stay neutral.
|
|
395
|
+
id: "zai.glm-5.3-plus",
|
|
396
|
+
creator: "z.ai",
|
|
397
|
+
family: "glm-5.3",
|
|
398
|
+
kind: "family",
|
|
399
|
+
predicate: isGlm53OrLater,
|
|
400
|
+
baseline: "zai.implicit-cache",
|
|
401
|
+
overlays: [],
|
|
402
|
+
legacy: true,
|
|
403
|
+
runtime: rt("glm53", {
|
|
404
|
+
thinkingIntegrity: true,
|
|
405
|
+
cacheRatio: "glm",
|
|
406
|
+
providerChange: "glm",
|
|
407
|
+
openRouterAffinity: true,
|
|
408
|
+
}),
|
|
409
|
+
boundary: "GLM-5.3 and later",
|
|
410
|
+
note: "Z.AI publishes no generational-inheritance rule and no explicit cache control. The baseline is implicit caching; the `<env>` relocation is a GLM-5.3-only CacheEngine overlay and is intentionally not inherited. No cache-control field is invented.",
|
|
411
|
+
inventoryRef: "§3 Z.AI GLM",
|
|
412
|
+
},
|
|
347
413
|
{
|
|
348
414
|
id: "xiaomi.mimo-v2.6",
|
|
349
415
|
creator: "xiaomi",
|
|
@@ -367,14 +433,42 @@ export const POLICY_REGISTRY = [
|
|
|
367
433
|
id: "xiaomi.mimo-v2.6-pro-ultraspeed",
|
|
368
434
|
creator: "xiaomi",
|
|
369
435
|
family: "mimo-v2.6",
|
|
370
|
-
kind: "
|
|
436
|
+
kind: "family",
|
|
437
|
+
pattern: /mimo-v2\.6-pro-ultraspeed/i,
|
|
371
438
|
exactIds: ["mimo-v2.6-pro-ultraspeed"],
|
|
372
439
|
baseline: "xiaomi.implicit-cache",
|
|
373
440
|
overlays: [],
|
|
374
|
-
legacy:
|
|
375
|
-
runtime: rt("
|
|
376
|
-
|
|
377
|
-
|
|
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.",
|
|
378
472
|
inventoryRef: "§4 Xiaomi MiMo",
|
|
379
473
|
},
|
|
380
474
|
{
|
|
@@ -54,7 +54,9 @@ import {
|
|
|
54
54
|
OVERLAYS,
|
|
55
55
|
POLICY_REGISTRY,
|
|
56
56
|
isDeepseekV4OrLater,
|
|
57
|
+
isGlm53OrLater,
|
|
57
58
|
isGpt56OrLater,
|
|
59
|
+
isMimoAfterV26,
|
|
58
60
|
resolveLegacyFamily,
|
|
59
61
|
resolvePolicy,
|
|
60
62
|
resolveRuntimePolicy,
|
|
@@ -324,11 +326,13 @@ test("MiMo V2.6 Flash/Pro match MiMo policy (openrouter + direct)", () => {
|
|
|
324
326
|
)
|
|
325
327
|
})
|
|
326
328
|
|
|
327
|
-
test("MiMo V2.5
|
|
329
|
+
test("MiMo V2.5 stays neutral; V2.6 Pro UltraSpeed now resolves (v0.4.5)", () => {
|
|
328
330
|
assert.equal(detectPolicy(M("openrouter", "xiaomi/mimo-v2.5")), POLICY_NEUTRAL)
|
|
329
331
|
assert.equal(detectPolicy(M("openrouter", "xiaomi/mimo-v2.5-pro")), POLICY_NEUTRAL)
|
|
330
332
|
assert.equal(detectPolicy(M("xiaomi", "mimo-v2.5")), POLICY_NEUTRAL)
|
|
331
|
-
|
|
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).
|
|
332
336
|
assert.equal(detectPolicy(M("xiaomi", "mimo-v2.6-flashx")), POLICY_NEUTRAL)
|
|
333
337
|
})
|
|
334
338
|
|
|
@@ -1447,7 +1451,7 @@ test("resolvePolicy: MiMo V2.6 Flash/Pro carry the overlay; Pro UltraSpeed is an
|
|
|
1447
1451
|
assert.equal(ultraspeed.matchType, "exact")
|
|
1448
1452
|
assert.deepEqual(overlayIds(ultraspeed), [])
|
|
1449
1453
|
const uEntry = POLICY_REGISTRY.find((e) => e.id === "xiaomi.mimo-v2.6-pro-ultraspeed")
|
|
1450
|
-
assert.equal(uEntry.policyStatus, "documented-series-member-
|
|
1454
|
+
assert.equal(uEntry.policyStatus, "documented-series-member-baseline-only")
|
|
1451
1455
|
|
|
1452
1456
|
const v25 = resolvePolicy(M("xiaomi", "mimo-v2.5"))
|
|
1453
1457
|
assert.equal(v25.family, "neutral")
|
|
@@ -1650,10 +1654,15 @@ async function runPolicyMigrationProbe() {
|
|
|
1650
1654
|
{ name: "deepseek-gateway", model: { providerID: "acme-gateway", id: "my-deepseek-mirror", api: { id: "my-deepseek-mirror" } }, expect: { policy: "deepseek", env: false, gpt: false, header: false } },
|
|
1651
1655
|
{ name: "glm-5.3-direct", model: { providerID: "zai", id: "glm-5.3", api: { id: "glm-5.3" } }, expect: { policy: "glm53", env: true, gpt: false, header: false } },
|
|
1652
1656
|
{ name: "glm-5.3-openrouter", model: { providerID: "openrouter", id: "z-ai/glm-5.3-flash", api: { id: "z-ai/glm-5.3-flash" } }, expect: { policy: "glm53", env: true, gpt: false, header: true } },
|
|
1657
|
+
{ name: "glm-5.4-direct", model: { providerID: "zai", id: "glm-5.4", api: { id: "glm-5.4" } }, expect: { policy: "glm53", env: false, gpt: false, header: false } },
|
|
1658
|
+
{ name: "glm-5.4-openrouter", model: { providerID: "openrouter", id: "z-ai/glm-5.4", api: { id: "z-ai/glm-5.4" } }, expect: { policy: "glm53", env: false, gpt: false, header: true } },
|
|
1653
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 } },
|
|
1654
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 } },
|
|
1655
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 } },
|
|
1656
|
-
{ 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 } },
|
|
1657
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 } },
|
|
1658
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 } },
|
|
1659
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 } },
|
|
@@ -1915,3 +1924,194 @@ test("v0.4.3: DeepSeek never receives OpenRouter affinity or GPT/GLM/MiMo fields
|
|
|
1915
1924
|
assert.equal(r.existingHeadersPreserved, true, `${name}: headers preserved`)
|
|
1916
1925
|
}
|
|
1917
1926
|
})
|
|
1927
|
+
|
|
1928
|
+
// ===========================================================================
|
|
1929
|
+
// v0.4.4 GLM-5.3-and-later family baseline vs the GLM-5.3-specific overlay
|
|
1930
|
+
//
|
|
1931
|
+
// Source: Z.AI docs re-verified 2026-09-27 (docs/cache-policy-inventory.md §3).
|
|
1932
|
+
// Z.AI documents implicit caching (no cache control) and publishes no
|
|
1933
|
+
// generational-inheritance rule; the `<env>` relocation is a CacheEngine overlay
|
|
1934
|
+
// with no first-party basis. GLM-5.2 and earlier stay neutral.
|
|
1935
|
+
// ===========================================================================
|
|
1936
|
+
|
|
1937
|
+
test("v0.4.4: isGlm53OrLater matches GLM-5.3+ version tokens only", () => {
|
|
1938
|
+
const inFamily = ["glm-5.3", "glm-5.3-flash", "glm-5.3-flashx", "glm-5.4", "glm-5.9", "glm-6", "z-ai/glm-5.3-flash"]
|
|
1939
|
+
for (const id of inFamily) assert.equal(isGlm53OrLater(id), true, `${id} is 5.3+`)
|
|
1940
|
+
const outOfFamily = ["glm-5.2", "glm-5.1", "glm-5", "glm-4.7", "glm-4.6", "glm-4.5", "glm-4.5-air", "glm-4-32b-0414-128k", ""]
|
|
1941
|
+
for (const id of outOfFamily) assert.equal(isGlm53OrLater(id), false, `${id} is pre-5.3`)
|
|
1942
|
+
})
|
|
1943
|
+
|
|
1944
|
+
test("v0.4.4: GLM-5.3 keeps its overlay; a later GLM gets the baseline only", () => {
|
|
1945
|
+
const g53 = resolvePolicy(M("zai", "glm-5.3"))
|
|
1946
|
+
assert.equal(g53.family, "glm-5.3")
|
|
1947
|
+
assert.equal(baseId(g53), "zai.implicit-cache")
|
|
1948
|
+
assert.deepEqual(overlayIds(g53), ["glm53.env-relocation"])
|
|
1949
|
+
|
|
1950
|
+
const g54 = resolvePolicy(M("zai", "glm-5.4"))
|
|
1951
|
+
assert.equal(g54.creator, "z.ai")
|
|
1952
|
+
assert.equal(g54.family, "glm-5.3")
|
|
1953
|
+
assert.equal(baseId(g54), "zai.implicit-cache") // same family baseline
|
|
1954
|
+
assert.deepEqual(overlayIds(g54), []) // overlay is NOT inherited
|
|
1955
|
+
|
|
1956
|
+
// Runtime capability separation: baseline diagnostics/transport yes, prompt rewrite no.
|
|
1957
|
+
const c53 = resolveRuntimePolicy(M("zai", "glm-5.3"))
|
|
1958
|
+
const c54 = resolveRuntimePolicy(M("zai", "glm-5.4"))
|
|
1959
|
+
assert.equal(c54.policy, "glm53")
|
|
1960
|
+
assert.equal(c54.envRelocation, null)
|
|
1961
|
+
assert.equal(c54.thinkingIntegrity, true)
|
|
1962
|
+
assert.equal(c54.cacheRatio, "glm")
|
|
1963
|
+
assert.equal(c54.providerChange, "glm")
|
|
1964
|
+
assert.equal(c54.openRouterAffinity, true)
|
|
1965
|
+
assert.equal(c53.envRelocation, "glm")
|
|
1966
|
+
|
|
1967
|
+
// Boundary metadata is traceable and the overlay is registered separately.
|
|
1968
|
+
const plus = POLICY_REGISTRY.find((e) => e.id === "zai.glm-5.3-plus")
|
|
1969
|
+
assert.equal(plus.boundary, "GLM-5.3 and later")
|
|
1970
|
+
assert.deepEqual(plus.overlays, [])
|
|
1971
|
+
assert.ok(plus.inventoryRef)
|
|
1972
|
+
})
|
|
1973
|
+
|
|
1974
|
+
test("v0.4.4: GLM-5.2 and earlier stay neutral", () => {
|
|
1975
|
+
for (const id of ["glm-5.2", "glm-5.1", "glm-5", "glm-4.7", "glm-4.6", "glm-4.5"]) {
|
|
1976
|
+
const r = resolvePolicy(M("zai", id))
|
|
1977
|
+
assert.equal(r.family, "neutral", `${id} neutral`)
|
|
1978
|
+
assert.deepEqual(overlayIds(r), [])
|
|
1979
|
+
assert.equal(resolveRuntimePolicy(M("zai", id)).policy, "neutral")
|
|
1980
|
+
}
|
|
1981
|
+
})
|
|
1982
|
+
|
|
1983
|
+
test("v0.4.4: legacy detectPolicy follows the GLM-5.3-and-later boundary", () => {
|
|
1984
|
+
assert.equal(detectPolicy(M("zai", "glm-5.3-flash")), POLICY_GLM53)
|
|
1985
|
+
assert.equal(detectPolicy(M("zai", "glm-5.4")), POLICY_GLM53)
|
|
1986
|
+
assert.equal(detectPolicy(M("zai", "glm-5.2")), POLICY_NEUTRAL)
|
|
1987
|
+
})
|
|
1988
|
+
|
|
1989
|
+
test("v0.4.4: <env> absent leaves system content unchanged", () => {
|
|
1990
|
+
const plain = "Stable instructions only.\nNo environment block here."
|
|
1991
|
+
const r = relocateVolatileEnvBlock(plain)
|
|
1992
|
+
assert.equal(r.changed, false)
|
|
1993
|
+
assert.equal(r.text, plain)
|
|
1994
|
+
})
|
|
1995
|
+
|
|
1996
|
+
test("v0.4.4: later GLM inherits the baseline but never the <env> rewrite (runtime)", async () => {
|
|
1997
|
+
const { results } = await policyMigrationResults()
|
|
1998
|
+
const g53 = results.find((r) => r.name === "glm-5.3-direct")
|
|
1999
|
+
const g54 = results.find((r) => r.name === "glm-5.4-direct")
|
|
2000
|
+
assert.ok(g53 && g54)
|
|
2001
|
+
// Identical system text with a valid <env> block present in both cases.
|
|
2002
|
+
assert.equal(g53.systemRelocated, true) // 5.3 overlay fires
|
|
2003
|
+
assert.equal(g54.systemRelocated, false) // later GLM does NOT inherit it
|
|
2004
|
+
assert.equal(g54.runtimePolicy, "glm53") // but the family baseline applies
|
|
2005
|
+
assert.equal(g54.gptOptionInjected, false)
|
|
2006
|
+
assert.equal(g54.affinityHeaderAttached, false)
|
|
2007
|
+
})
|
|
2008
|
+
|
|
2009
|
+
test("v0.4.4: GLM OpenRouter affinity is transport-gated for later GLM too", async () => {
|
|
2010
|
+
const { results } = await policyMigrationResults()
|
|
2011
|
+
const or = results.find((r) => r.name === "glm-5.4-openrouter")
|
|
2012
|
+
const direct = results.find((r) => r.name === "glm-5.4-direct")
|
|
2013
|
+
assert.equal(or.affinityHeaderAttached, true)
|
|
2014
|
+
assert.equal(or.systemRelocated, false)
|
|
2015
|
+
assert.equal(direct.affinityHeaderAttached, false)
|
|
2016
|
+
assert.equal(or.existingHeadersPreserved, true)
|
|
2017
|
+
assert.equal(direct.existingHeadersPreserved, true)
|
|
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
|
+
})
|