fix: revert model-language pinning, keep language setting UI-only

The language setting should govern the interface only, not the model.
Remove LanguagePolicyFor and the hardcoded Chinese/English policies so
the model mirrors whatever language the user writes in per message.
This commit is contained in:
Sivan committed 2026-06-01 22:13:58 +08:00
1 parent 87d604586e
commit 40dd6f2013
3 files changed
+4 -34

No files matched your search

+1 -6
View File
@@ -22,7 +22,6 @@ import (
"reasonix/internal/control"
"reasonix/internal/event"
"reasonix/internal/hook"
"reasonix/internal/i18n"
"reasonix/internal/jobs"
"reasonix/internal/lsp"
"reasonix/internal/memory"
@@ -67,7 +66,6 @@ func Build(ctx context.Context, opts Options) (*control.Controller, error) {
if err != nil {
return nil, err
}
resolvedLanguage := i18n.DetectLanguage(cfg.Language)
modelName := opts.Model
if modelName == "" {
modelName = cfg.DefaultModel
@@ -104,10 +102,7 @@ func Build(ctx context.Context, opts Options) (*control.Controller, error) {
if st, ok := outputstyle.Resolve(cfg.Agent.OutputStyle, outputstyle.Dirs()); ok {
sysPrompt = outputstyle.Apply(sysPrompt, st)
}
// Append the language policy once so the model, including provider-exposed
// visible reasoning, follows the selected UI language without per-turn prompt
// injection. Static within a session, so it stays in the cache-stable prefix.
sysPrompt += "\n\n" + config.LanguagePolicyFor(resolvedLanguage)
sysPrompt += "\n\n" + config.LanguagePolicy
// Persistent memory (REASONIX.md / AGENTS.md hierarchy + auto-memory index)
// folds into the system prompt exactly here, once: it becomes part of the
+3 -9
View File
@@ -217,12 +217,11 @@ api_key_env = "REASONIX_TEST_KEY_UNSET"
}
}
func TestBuildLanguagePolicyFollowsConfiguredLanguage(t *testing.T) {
func TestBuildLanguagePolicyIsAppended(t *testing.T) {
dir := t.TempDir()
t.Chdir(dir)
writeFile(t, dir, "reasonix.toml", `
default_model = "test-model"
language = "zh"
[codegraph]
enabled = false
@@ -245,11 +244,8 @@ api_key_env = "REASONIX_TEST_KEY_UNSET"
defer ctrl.Close()
sys := systemMessage(ctrl.History())
if !strings.Contains(sys, "Reply in Chinese") {
t.Fatalf("configured Chinese language policy missing from system prompt:\n%s", sys)
}
if !strings.Contains(sys, "visible reasoning") {
t.Fatalf("language policy should cover provider-visible reasoning:\n%s", sys)
if !strings.Contains(sys, config.LanguagePolicy) {
t.Fatalf("language policy missing from system prompt:\n%s", sys)
}
}
@@ -265,8 +261,6 @@ func systemMessage(msgs []provider.Message) string {
func stripLanguagePolicy(s string) string {
s = strings.TrimSpace(s)
for _, policy := range []string{
config.LanguagePolicyFor("zh"),
config.LanguagePolicyFor("en"),
config.LanguagePolicy,
} {
s = strings.TrimSpace(strings.TrimSuffix(s, policy))
-19
View File
@@ -307,25 +307,6 @@ const LanguagePolicy = `Reply in the same language the user is using in their mo
`whenever they switch. Let this also guide the language you think in. Always keep code, ` +
`identifiers, file paths, shell commands, and technical terms in their original form — never translate them.`
const chineseLanguagePolicy = `Reply in Chinese. When the provider exposes visible reasoning, status text, or thought summaries, keep those in Chinese as well. Always keep code, identifiers, file paths, shell commands, and technical terms in their original form — never translate them.`
const englishLanguagePolicy = `Reply in English. When the provider exposes visible reasoning, status text, or thought summaries, keep those in English as well. Always keep code, identifiers, file paths, shell commands, and technical terms in their original form — never translate them.`
// LanguagePolicyFor returns the cache-stable language instruction for the
// resolved UI language. It is folded into the system prompt once at controller
// build time; changing language rebuilds the session prefix rather than adding a
// dynamic instruction to every user turn.
func LanguagePolicyFor(tag string) string {
switch strings.ToLower(strings.TrimSpace(tag)) {
case "zh":
return chineseLanguagePolicy
case "en":
return englishLanguagePolicy
default:
return LanguagePolicy
}
}
// Default returns the built-in default configuration (DeepSeek + MiMo presets).
func Default() *Config {
return &Config{