Problem
When using a local llama.cpp server (via openai-completions provider), the KV cache is fully invalidated on every message because the system prompt changes between turns.
Root Cause
buildInboundMetaSystemPrompt() injects per-message metadata into the system prompt (via extraSystemPrompt), including message_id which changes every message:
{
"schema": "openclaw.inbound_meta.v1",
"message_id": "2959",
"sender_id": "414434471",
"chat_id": "telegram:414434471",
...
}
For Anthropic/OpenAI this is fine — they handle caching server-side. But for llama.cpp, the KV cache works by matching the token prefix byte-for-byte. Any change in the system prompt (first message in the conversation) shifts the entire token sequence and forces a full reprocessing of the entire context.
Additionally, buildInboundUserContextPrefix() prepends changing metadata (including message_id) to each user message.
Impact
With a 196K context window model like MiniMax-M2.5, every message requires reprocessing the full conversation history from scratch, making the agent progressively slower and wasting compute.
Suggested Fix
One or more of:
- Strip volatile fields (
message_id) from inbound meta for openai-completions providers
- Move per-message metadata out of the system prompt and into the last user message only, so the system prefix stays stable and cacheable
- Add a provider-level config like
"stableSystemPrompt": true that suppresses per-message metadata injection into the system prompt
- Move the inbound meta block entirely to user messages instead of appending to the system prompt
Option 2 or 4 would be the cleanest — the system prompt stays byte-stable across turns, and llama.cpp can reuse the KV cache for the entire prefix.
Environment
- OpenClaw 2026.2.17
- Provider:
openai-completions pointing to llama.cpp server
- Model: MiniMaxAI/MiniMax-M2.5 (196K context)
Relevant Code
src/auto-reply/reply/inbound-meta.ts → buildInboundMetaSystemPrompt()
src/auto-reply/reply/get-reply-run.ts → where extraSystemPrompt is assembled
Problem
When using a local llama.cpp server (via
openai-completionsprovider), the KV cache is fully invalidated on every message because the system prompt changes between turns.Root Cause
buildInboundMetaSystemPrompt()injects per-message metadata into the system prompt (viaextraSystemPrompt), includingmessage_idwhich changes every message:{ "schema": "openclaw.inbound_meta.v1", "message_id": "2959", "sender_id": "414434471", "chat_id": "telegram:414434471", ... }For Anthropic/OpenAI this is fine — they handle caching server-side. But for llama.cpp, the KV cache works by matching the token prefix byte-for-byte. Any change in the system prompt (first message in the conversation) shifts the entire token sequence and forces a full reprocessing of the entire context.
Additionally,
buildInboundUserContextPrefix()prepends changing metadata (includingmessage_id) to each user message.Impact
With a 196K context window model like MiniMax-M2.5, every message requires reprocessing the full conversation history from scratch, making the agent progressively slower and wasting compute.
Suggested Fix
One or more of:
message_id) from inbound meta foropenai-completionsproviders"stableSystemPrompt": truethat suppresses per-message metadata injection into the system promptOption 2 or 4 would be the cleanest — the system prompt stays byte-stable across turns, and llama.cpp can reuse the KV cache for the entire prefix.
Environment
openai-completionspointing to llama.cpp serverRelevant Code
src/auto-reply/reply/inbound-meta.ts→buildInboundMetaSystemPrompt()src/auto-reply/reply/get-reply-run.ts→ whereextraSystemPromptis assembled