Summary
When using magic-context in a non-English conversation (in my case Russian), the primary model's output progressively drifts from the user's language to English over a session. The drift tracks the session growing long enough that the historian compacts history and memory gets injected.
Running the identical models in another harness without magic-context shows no drift — output stays Russian throughout. With magic-context enabled, drift reliably appears. This points at magic-context's injected context: every English-only text stream it injects pulls the model's output language toward English, and several such streams are injected continuously.
I'd like to request a language-preservation option so non-English users can keep the conversation language intact.
Environment
- Harness: OpenCode
- Plugin: @cortexkit/opencode-magic-context 0.26.0
- OS: Windows
- Session language: Russian (reproducible with any non-English language)
- Relevant config (for repro context):
history_budget_percentage: 0.22, memory.injection_budget_tokens: 8000, memory.auto_search.enabled: true
- A system /
AGENTS.md directive instructs the model to respond in Russian — drift still happens.
What happens vs. expected
- What happens: Early turns are fully Russian. As the session grows, replies increasingly slip into English — first occasional sentences/terms, then whole responses — even though the user keeps writing in Russian and a "respond in Russian" directive is present.
- Expected: The model keeps responding in the conversation's language for the whole session, regardless of how history is compacted or what memory/context is injected.
Root cause (grounded in the installed 0.26.0 bundle)
The issue is structural, not a single string. magic-context injects several independent English-only text streams into the live context, none carrying any instruction to use the conversation's language. There is also no config key to set output language, and the agent prompts are full overrides, so a user can't safely append a one-line "preserve language" instruction.
Line refs are from the installed node_modules/@cortexkit/opencode-magic-context/dist/index.js:
-
Historian compartment summaries — injected <session-history> block. COMPARTMENT_AGENT_SYSTEM_PROMPT (163055) is entirely English and has no instruction to write the summary in the conversation's language. The one language-touching rule ("Wording — default verbatim", 163375) applies only to U: user-directive lines; the narrative tiers (P1–P4), <facts>, <events>, <user_observations> are the historian's own paraphrase and default to English. Crucially, the injection doesn't just add a summary — in prepareCompartmentInjection (169582) the raw messages up to the compartment boundary are spliced out (messages.splice(0, messages.length, ...remaining)) and replaced by the English summary block (buildCompartmentBlock 169662). So as the session grows, the visible "history" becomes progressively more English — which directly matches the "progressive drift over a session" symptom.
-
Dreamer-extracted memories — injected <project-memory> / <user-profile> block. DREAMER_SYSTEM_PROMPT (178552) is English-only and instructs "Use present-tense operational language in all memory rewrites" (178573) with English canonical-wording examples. Memories are normalized to English and re-injected each session (renderMemoryBlock 169619, renderUserProfileBlock 170146).
-
memory.auto_search hints — appended to the user message on the wire. Enabled by default (schema 14975–14988). On every eligible user turn (prompt ≥ 20 chars and top hit score ≥ 0.6), buildAutoSearchHint (187163) appends a <ctx-search-hint> block with a hardcoded-English header ("Your memory may contain N related fragment(s):", 187176) and footer (187177). Because this rides on the user turn itself for every eligible message, it's especially drift-relevant.
-
"## Magic Context" guidance — pushed into the primary agent's system prompt each session. buildMagicContextSection (189959) concatenates LONG_TERM_PARTNER_FRAME + BASE_INTRO + GENERIC_SECTION (+ optional temporal / caveman blocks), all English, injected via output.system.push(guidance) (190048). Persistent English in the live system prompt for the whole session.
Two findings make this hard to work around as a user:
- No language/locale config exists at any level (core / historian / dreamer / memory / sidekick / auto_search). A full-bundle search for
output language / preserve.*language / same language / locale config keys returns only token-vocab and setlocale false positives. (Same result against the public CONFIGURATION.md.)
historian.prompt / dreamer.prompt / sidekick.prompt are full system-prompt overrides, not additive. buildHiddenAgentConfig (193455) spreads a supplied prompt over the constant, and sidekick resolves system = system_prompt?.trim() || prompt?.trim() || SIDEKICK_SYSTEM_PROMPT (178996). So a user who wants to add "preserve the conversation language" must replace the entire (~700-line) compaction prompt and forfeit future upstream prompt improvements.
Also worth noting: the internal historian/dreamer agents never see a "respond in Russian" user directive (they're hidden agents, skipped in the injection handler around 190019), so that single user-level instruction competes against several continuously-injected English blocks and loses.
I checked existing issues / PRs / discussions and the changelog through the latest releases — nothing mentions output language, locale, multilingual, or language drift, so this doesn't appear to be tracked yet.
Reproduction
- Install
@cortexkit/opencode-magic-context (0.26.0) in OpenCode with defaults (memory.auto_search.enabled: true).
- Start a session entirely in a non-English language (e.g. Russian). Optionally add a "respond in Russian" system /
AGENTS.md directive.
- Continue long enough that (a) the historian compacts history into
<session-history> compartments, and (b) memory injection / <ctx-search-hint> start surfacing.
- Observe responses increasingly switching to English as the session grows, while user input stays in the original language.
Impact
- Non-English users effectively can't sustain a conversation in their own language once a session is long enough for compaction + memory injection to kick in.
- There's no configuration-level workaround; the only escape hatch (overriding the agent prompts) means wholesale-replacing the compaction prompts and giving up upstream improvements.
- This affects every language other than English and grows worse with session length — exactly the long sessions magic-context is built for.
Proposed solutions (ranked)
-
(Preferred) An optional language/locale setting honored across all injection points. E.g. a language / output_language key (or per-agent historian.output_language, dreamer.output_language) that, when set, appends a short "write summaries / memories / hints in <language>" directive to the historian, dreamer, and sidekick prompts and to the <ctx-search-hint> header/footer and the "## Magic Context" guidance. One knob covers all four English-only sources.
-
An additive prompt-suffix option (e.g. historian.prompt_suffix / dreamer.prompt_suffix / sidekick.prompt_suffix) so users can append a "preserve the conversation's language" line without replacing the entire compaction prompt. Complements (1) and is useful beyond language.
-
Auto-detect and mirror the conversation language. Detect the dominant language of recent user turns and have the historian / dreamer / auto-search components produce their text in that language by default. Lower priority (detection adds complexity and likely needs an override), but it would fix the default experience with no config.
Happy to share a transcript showing the drift, or to test a patch. Thanks for building this — really useful plugin; language preservation would make it work well for non-English sessions too.
Summary
When using magic-context in a non-English conversation (in my case Russian), the primary model's output progressively drifts from the user's language to English over a session. The drift tracks the session growing long enough that the historian compacts history and memory gets injected.
Running the identical models in another harness without magic-context shows no drift — output stays Russian throughout. With magic-context enabled, drift reliably appears. This points at magic-context's injected context: every English-only text stream it injects pulls the model's output language toward English, and several such streams are injected continuously.
I'd like to request a language-preservation option so non-English users can keep the conversation language intact.
Environment
history_budget_percentage: 0.22,memory.injection_budget_tokens: 8000,memory.auto_search.enabled: trueAGENTS.mddirective instructs the model to respond in Russian — drift still happens.What happens vs. expected
Root cause (grounded in the installed 0.26.0 bundle)
The issue is structural, not a single string. magic-context injects several independent English-only text streams into the live context, none carrying any instruction to use the conversation's language. There is also no config key to set output language, and the agent prompts are full overrides, so a user can't safely append a one-line "preserve language" instruction.
Line refs are from the installed
node_modules/@cortexkit/opencode-magic-context/dist/index.js:Historian compartment summaries — injected
<session-history>block.COMPARTMENT_AGENT_SYSTEM_PROMPT(163055) is entirely English and has no instruction to write the summary in the conversation's language. The one language-touching rule ("Wording — default verbatim",163375) applies only toU:user-directive lines; the narrative tiers (P1–P4),<facts>,<events>,<user_observations>are the historian's own paraphrase and default to English. Crucially, the injection doesn't just add a summary — inprepareCompartmentInjection(169582) the raw messages up to the compartment boundary are spliced out (messages.splice(0, messages.length, ...remaining)) and replaced by the English summary block (buildCompartmentBlock169662). So as the session grows, the visible "history" becomes progressively more English — which directly matches the "progressive drift over a session" symptom.Dreamer-extracted memories — injected
<project-memory>/<user-profile>block.DREAMER_SYSTEM_PROMPT(178552) is English-only and instructs "Use present-tense operational language in all memory rewrites" (178573) with English canonical-wording examples. Memories are normalized to English and re-injected each session (renderMemoryBlock169619,renderUserProfileBlock170146).memory.auto_searchhints — appended to the user message on the wire. Enabled by default (schema14975–14988). On every eligible user turn (prompt ≥ 20 chars and top hit score ≥ 0.6),buildAutoSearchHint(187163) appends a<ctx-search-hint>block with a hardcoded-English header ("Your memory may contain N related fragment(s):",187176) and footer (187177). Because this rides on the user turn itself for every eligible message, it's especially drift-relevant."## Magic Context" guidance — pushed into the primary agent's system prompt each session.
buildMagicContextSection(189959) concatenatesLONG_TERM_PARTNER_FRAME+BASE_INTRO+GENERIC_SECTION(+ optional temporal / caveman blocks), all English, injected viaoutput.system.push(guidance)(190048). Persistent English in the live system prompt for the whole session.Two findings make this hard to work around as a user:
output language/preserve.*language/same language/localeconfig keys returns only token-vocab andsetlocalefalse positives. (Same result against the publicCONFIGURATION.md.)historian.prompt/dreamer.prompt/sidekick.promptare full system-prompt overrides, not additive.buildHiddenAgentConfig(193455) spreads a suppliedpromptover the constant, and sidekick resolvessystem = system_prompt?.trim() || prompt?.trim() || SIDEKICK_SYSTEM_PROMPT(178996). So a user who wants to add "preserve the conversation language" must replace the entire (~700-line) compaction prompt and forfeit future upstream prompt improvements.Also worth noting: the internal historian/dreamer agents never see a "respond in Russian" user directive (they're hidden agents, skipped in the injection handler around
190019), so that single user-level instruction competes against several continuously-injected English blocks and loses.I checked existing issues / PRs / discussions and the changelog through the latest releases — nothing mentions output language, locale, multilingual, or language drift, so this doesn't appear to be tracked yet.
Reproduction
@cortexkit/opencode-magic-context(0.26.0) in OpenCode with defaults (memory.auto_search.enabled: true).AGENTS.mddirective.<session-history>compartments, and (b) memory injection /<ctx-search-hint>start surfacing.Impact
Proposed solutions (ranked)
(Preferred) An optional language/locale setting honored across all injection points. E.g. a
language/output_languagekey (or per-agenthistorian.output_language,dreamer.output_language) that, when set, appends a short "write summaries / memories / hints in<language>" directive to the historian, dreamer, and sidekick prompts and to the<ctx-search-hint>header/footer and the "## Magic Context" guidance. One knob covers all four English-only sources.An additive prompt-suffix option (e.g.
historian.prompt_suffix/dreamer.prompt_suffix/sidekick.prompt_suffix) so users can append a "preserve the conversation's language" line without replacing the entire compaction prompt. Complements (1) and is useful beyond language.Auto-detect and mirror the conversation language. Detect the dominant language of recent user turns and have the historian / dreamer / auto-search components produce their text in that language by default. Lower priority (detection adds complexity and likely needs an override), but it would fix the default experience with no config.
Happy to share a transcript showing the drift, or to test a patch. Thanks for building this — really useful plugin; language preservation would make it work well for non-English sessions too.