Skip to content

fix(mistral): enable prompt cache key compat#88976

Merged
steipete merged 4 commits into
openclaw:mainfrom
Alix-007:issue-83709-mistral-prompt-cache-v2
Jun 2, 2026
Merged

fix(mistral): enable prompt cache key compat#88976
steipete merged 4 commits into
openclaw:mainfrom
Alix-007:issue-83709-mistral-prompt-cache-v2

Conversation

@Alix-007

@Alix-007 Alix-007 commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

Fixes #83709.

Summary

  • mark bundled Mistral OpenAI-compatible models as supporting prompt_cache_key
  • keep Mistral compat normalization and resolved-compat reuse checks aware of cache-key support without advertising unsupported long retention
  • price bundled Mistral cached reads at the documented 10% input-token rate and migrate persisted bundled Mistral model rows that still have old cacheRead: 0 costs
  • document cache-key support separately from long-retention support for OpenAI-compatible providers

Verification

  • node scripts/run-vitest.mjs src/commands/doctor-legacy-config.migrations.test.ts extensions/mistral/api.test.ts extensions/mistral/model-definitions.test.ts src/agents/openai-transport-stream.test.ts src/llm/providers/openai-completions.test.ts
  • pnpm exec oxlint src/commands/doctor/shared/legacy-config-core-normalizers.ts src/commands/doctor/shared/legacy-config-compatibility-base.ts src/commands/doctor-legacy-config.migrations.test.ts
  • git diff --check

Real behavior proof

Behavior addressed: Bundled Mistral OpenAI-compatible models advertise supportsPromptCacheKey: true (without unsupported long retention); cached reads are priced at the documented nonzero Mistral rate; and doctor migration upgrades persisted bundled Mistral rows still carrying cacheRead: 0 while preserving custom nonzero cached-read costs.

Real environment tested: Linux x86_64, Node.js v22.22.0, HEAD b150a44ecc8af8b75d98ce90b82159c94418e379 rebased onto origin/main 086274fd7e7a33d7085c95373b19cd18945c4b59. The rebase carried only type-level adjustments (a generic on normalizeLegacyMistralModelCost to preserve the input type, and a reasoning: false test fixture field now required by ModelDefinitionConfig) with no runtime behavior change. Production functions are driven directly via node --import tsx, plus the focused Vitest suites.

Exact steps or command run after this patch:

# Drive the real production functions (compat advertisement + doctor migration):
node --import tsx -e 'Promise.all([import("./extensions/mistral/model-definitions.js"),import("./extensions/mistral/api.js"),import("./src/commands/doctor/shared/legacy-config-core-normalizers.js")]).then(([md,api,norm])=>{
  const compat=api.applyMistralModelCompat(md.buildMistralModelDefinition());
  console.log("compat:",JSON.stringify(compat.compat));
  const cfg={models:{providers:{mistral:{models:[
    {id:"mistral-large-latest",name:"L",reasoning:false,input:["text"],cost:{input:2,output:6,cacheRead:0,cacheWrite:0},contextWindow:262144,maxTokens:16384},
    {id:"custom-mistral-model",name:"C",reasoning:false,input:["text"],cost:{input:1,output:2,cacheRead:0.5,cacheWrite:0},contextWindow:128000,maxTokens:32000}]}}}};
  const ch=[];const m=norm.normalizeLegacyMistralModelDefaults(cfg,ch);
  console.log("changes:",JSON.stringify(ch));
  console.log("cacheRead large/custom:",m.models.providers.mistral.models[0].cost.cacheRead,m.models.providers.mistral.models[1].cost.cacheRead);
})'

# Focused regression suites:
OPENCLAW_VITEST_MAX_WORKERS=1 node scripts/run-vitest.mjs run \
  extensions/mistral/api.test.ts extensions/mistral/model-definitions.test.ts --reporter=dot

Evidence after fix:

compat: {"supportsStore":false,"supportsPromptCacheKey":true,"supportsLongCacheRetention":false,"maxTokensField":"max_tokens","supportsReasoningEffort":false}
changes: ["Normalized models.providers.mistral.models[0].cost.cacheRead (0 → 0.05) for Mistral prompt-cache billing."]
cacheRead large/custom: 0.05 0.5

 Test Files  2 passed (2)
      Tests  16 passed (16)

Observed result after fix: The bundled Mistral model advertises supportsPromptCacheKey: true with long retention disabled; doctor migration rewrites the stale bundled cacheRead: 0 row to the documented 0.05 rate while leaving the custom 0.5 row untouched; the focused Mistral suites pass 16/16. CI check-test-types / check-prod-types / check-lint are green on this head.

What was not tested: A live Mistral API cache hit (no MISTRAL_API_KEY in this environment); cache-hit timing is best-effort. The fix is exercised through the production compat / model-definition / migration functions and unit tests rather than a live cache cycle.

@openclaw-barnacle openclaw-barnacle Bot added extensions: mistral size: XS triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. labels Jun 1, 2026
@clawsweeper

clawsweeper Bot commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge. Reviewed June 1, 2026, 9:01 PM ET / 01:01 UTC.

Summary
The PR enables Mistral prompt_cache_key support, disables unsupported long-retention forwarding for Mistral, updates cached-read pricing/migration, and documents the split between cache-key and long-retention support.

PR surface: Source +80, Tests +205, Docs 0. Total +285 across 13 files.

Reproducibility: yes. from source inspection: current main lacks supportsPromptCacheKey on the Mistral compat patch while both agent and provider transports require that flag to emit prompt_cache_key. I did not run a live Mistral cache-hit test because no key is available in the provided proof.

Review metrics: 2 noteworthy metrics.

  • Mistral cached-read defaults: 8 changed, 0 added, 0 removed. Bundled model cost defaults feed user-visible cost accounting and persisted config repair.
  • Compatibility migration surface: 1 doctor migration path extended. Upgrade behavior matters because old persisted bundled Mistral rows can be rewritten during repair.

Merge readiness
Overall: 🐚 platinum hermit
Proof: 🦞 diamond lobster
Patch quality: 🐚 platinum hermit
Result: ready for maintainer review.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • [P2] Maintainer should explicitly accept or reject the cached-read migration and long-retention compatibility behavior before merge.

Risk before merge

  • [P1] The PR intentionally changes bundled Mistral cached-read defaults and doctor rewrites old zero cached-read rows to nonzero costs, so existing users can see changed cost accounting after upgrade repair.
  • [P1] The long-retention split is right for Mistral, but it changes behavior for custom OpenAI-compatible completions configs that relied on cacheRetention: "long" without explicit compat.supportsPromptCacheKey: true.

Maintainer options:

  1. Accept the upgrade behavior (recommended)
    A maintainer can explicitly accept the cached-read migration and long-retention opt-out because the patch documents the behavior and tests preservation of custom costs.
  2. Ask for extra upgrade proof
    If maintainers want stronger evidence, request one more proof pass showing an upgraded persisted Mistral config before and after doctor --fix.

Next step before merge

  • [P2] The patch has no narrow automated repair target; it needs maintainer compatibility sign-off on upgrade cost migration and long-retention behavior.

Security
Cleared: No supply-chain, secret-handling, permission, workflow, dependency, or code-execution security concern was found in the diff.

Review details

Best possible solution:

Land this owner-boundary fix after maintainer compatibility sign-off: Mistral should declare cache-key support with long-retention disabled, transports should honor those separate flags, and doctor should migrate only known zero-cost bundled rows while preserving custom costs.

Do we have a high-confidence way to reproduce the issue?

Yes from source inspection: current main lacks supportsPromptCacheKey on the Mistral compat patch while both agent and provider transports require that flag to emit prompt_cache_key. I did not run a live Mistral cache-hit test because no key is available in the provided proof.

Is this the best way to solve the issue?

Yes, this is the right owner-boundary shape if maintainers accept the upgrade semantics: the Mistral plugin owns the compat declaration, shared transports honor generic flags, and doctor handles old persisted bundled defaults. The remaining question is compatibility acceptance, not a narrower code defect.

AGENTS.md: found and applied where relevant.

Codex review notes: model gpt-5.5, reasoning high; reviewed against 459abfc26baf.

Label changes

Label changes:

  • add proof: sufficient: Contributor real behavior proof is sufficient. The PR body now contains current-head terminal proof for the production compat and doctor-migration functions plus focused test output; live Mistral cache-hit behavior remains untested due to missing credentials.
  • add rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🦞 diamond lobster and patch quality is 🐚 platinum hermit.
  • add status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (terminal): The PR body now contains current-head terminal proof for the production compat and doctor-migration functions plus focused test output; live Mistral cache-hit behavior remains untested due to missing credentials.
  • remove rating: 🦪 silver shellfish: Current PR rating is rating: 🐚 platinum hermit, so this older rating label is no longer current.
  • remove status: 📣 needs proof: Current PR status label is status: 👀 ready for maintainer look.

Label justifications:

  • P2: This is a normal-priority provider compatibility fix with meaningful cost-accounting and caching impact but limited blast radius.
  • merge-risk: 🚨 compatibility: The PR changes cached-read defaults, doctor upgrade behavior, and OpenAI-compatible long-retention gating for existing configurations.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🦞 diamond lobster and patch quality is 🐚 platinum hermit.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (terminal): The PR body now contains current-head terminal proof for the production compat and doctor-migration functions plus focused test output; live Mistral cache-hit behavior remains untested due to missing credentials.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR body now contains current-head terminal proof for the production compat and doctor-migration functions plus focused test output; live Mistral cache-hit behavior remains untested due to missing credentials.
Evidence reviewed

PR surface:

Source +80, Tests +205, Docs 0. Total +285 across 13 files.

View PR surface stats
Area Files Added Removed Net
Source 7 110 30 +80
Tests 5 208 3 +205
Docs 1 1 1 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 13 319 34 +285

What I checked:

  • Current main lacks Mistral cache-key compat: On current main, MISTRAL_MODEL_TRANSPORT_PATCH contains supportsStore and maxTokensField but does not advertise supportsPromptCacheKey, while the completions transport gates cache-key emission on that compat flag. (extensions/mistral/api.ts:15, 459abfc26baf)
  • Current main transport gate: Current main only emits prompt_cache_key for OpenAI-compatible completions when compat.supportsPromptCacheKey is true, so bundled Mistral models cannot get the key without the plugin compat change. (src/agents/openai-transport-stream.ts:3665, 459abfc26baf)
  • PR adds the Mistral compat flags: The PR branch sets supportsPromptCacheKey: true and supportsLongCacheRetention: false in the Mistral transport patch and includes those fields in the resolved-compat reuse check. (extensions/mistral/api.ts:15, b150a44ecc8a)
  • PR separates key support from long retention: The PR branch keeps prompt_cache_key when a model opts in, but only sends prompt_cache_retention when supportsLongCacheRetention remains enabled. (src/llm/providers/openai-completions.ts:606, b150a44ecc8a)
  • Doctor migration preserves custom costs: The migration only rewrites known bundled Mistral model rows whose cacheRead is exactly zero, and the regression test preserves custom nonzero costs plus unknown custom model costs. (src/commands/doctor-legacy-config.migrations.test.ts:1665, b150a44ecc8a)
  • Dependency contract: Official Mistral docs describe prompt_cache_key, cached token reporting in usage.prompt_tokens_details.cached_tokens, and cached tokens billed at 10% of the standard input token price. (docs.mistral.ai)

Likely related people:

  • Vincent Koc: Current main blame and shortlog for the Mistral compat, OpenAI-compatible prompt-cache transport, and doctor normalizer paths point to Vincent Koc; the PR branch also includes the commit that separates cache-key support from long-retention support. (role: recent area contributor and adjacent reviewer; confidence: high; commits: afdf9aaea0a0, eeb9cf196a42; files: extensions/mistral/api.ts, src/llm/providers/openai-completions.ts, src/agents/openai-transport-stream.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P2 Normal backlog priority with limited blast radius. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. labels Jun 1, 2026
@openclaw-barnacle openclaw-barnacle Bot added proof: supplied External PR includes structured after-fix real behavior proof. agents Agent runtime and tooling size: S and removed triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. size: XS labels Jun 1, 2026
@vincentkoc vincentkoc self-assigned this Jun 1, 2026
@vincentkoc vincentkoc added proof: sufficient ClawSweeper judged the real behavior proof convincing. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. and removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Jun 1, 2026
@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. merge-risk: 🚨 other 🚨 Merging this PR has meaningful risk outside the owned taxonomy. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. and removed status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. proof: sufficient ClawSweeper judged the real behavior proof convincing. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Jun 1, 2026
@openclaw-barnacle openclaw-barnacle Bot added size: M and removed size: S proof: sufficient ClawSweeper judged the real behavior proof convincing. labels Jun 1, 2026
@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. and removed rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. labels Jun 1, 2026
@Alix-007 Alix-007 force-pushed the issue-83709-mistral-prompt-cache-v2 branch from 1dc3236 to b150a44 Compare June 2, 2026 00:23
@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label Jun 2, 2026
@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. and removed rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. labels Jun 2, 2026
@Alix-007

Alix-007 commented Jun 2, 2026

Copy link
Copy Markdown
Contributor Author

Rebased onto latest main (230 commits) and refreshed the real-behavior proof for the current head b150a44ecc. The rebase carried only type-level adjustments (generic on normalizeLegacyMistralModelCost, plus a reasoning: false fixture field now required by ModelDefinitionConfig) — no runtime behavior change. Re-verified at this head: applyMistralModelCompat advertises supportsPromptCacheKey: true, doctor migration rewrites stale cacheRead: 00.05 while preserving custom rates, and the focused Mistral suites pass 16/16. check-test-types / check-prod-types / check-lint are green.

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

Re-review progress:

@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. and removed rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Jun 2, 2026
@steipete steipete force-pushed the issue-83709-mistral-prompt-cache-v2 branch from b150a44 to adcb9a7 Compare June 2, 2026 12:46
@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label Jun 2, 2026
@steipete

steipete commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

Land-ready after maintainer rebase onto current main.

Proof:

  • Dependency contract checked against Mistral official OpenAPI/docs: chat requests expose prompt_cache_key; usage exposes prompt_tokens_details.cached_tokens; Mistral prompt-cache pricing documents cached tokens at 10% of input tokens; no prompt_cache_retention field is present in the Mistral OpenAPI schema.
  • Local current-main focused tests: node scripts/run-vitest.mjs src/commands/doctor-legacy-config.migrations.test.ts extensions/mistral/api.test.ts extensions/mistral/model-definitions.test.ts src/agents/openai-transport-stream.test.ts src/llm/providers/openai-completions.test.ts passed, 4 Vitest shards.
  • Local formatting: node ./node_modules/.bin/oxfmt --check ... && git diff --check passed.
  • Local type contract: pnpm check:test-types passed.
  • Exact-head CI on adcb9a7824763ed919f2fad0859e6d817e886693 passed, including Real behavior proof, build-artifacts, check-lint, check-prod-types, check-test-types, check-shrinkwrap, dependency-guard, Security High, Critical Quality selected shard, and selected node shards.

No known proof gaps.

@steipete steipete merged commit 1824aa0 into openclaw:main Jun 2, 2026
163 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling commands Command implementations docs Improvements or additions to documentation extensions: mistral merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. P2 Normal backlog priority with limited blast radius. proof: supplied External PR includes structured after-fix real behavior proof. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. size: M status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Add supportsPromptCacheKey to Mistral transport compat patch

3 participants