From c0a81c84e7649e0d13c1c505f9c7cbf6f9538c7f Mon Sep 17 00:00:00 2001 From: Gahow Wang Date: Tue, 2 Jun 2026 15:19:50 +0800 Subject: [PATCH] server: canonical harmony system message in gpt-oss fallback build_prompt_gpt_oss (the hardcoded builder used when a gpt-oss model ships no Jinja chat template) emitted the same malformed "You are a helpful assistant." system message that destabilized the CLI. Replace it with the canonical harmony system message (identity / knowledge cutoff / current date via strftime_now / Reasoning: low / channels), matching the chat_template.jinja build_system_message macro and the xserv-chat fix. Dormant for gpt-oss-20b (it ships a Jinja template, so the template path runs), but correct now for any gpt-oss model without one. Co-Authored-By: Claude Opus 4.8 --- crates/xserv-server/src/api.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/crates/xserv-server/src/api.rs b/crates/xserv-server/src/api.rs index 723afed..c984700 100644 --- a/crates/xserv-server/src/api.rs +++ b/crates/xserv-server/src/api.rs @@ -198,8 +198,17 @@ fn build_prompt_hardcoded(messages: &[Message], model_type: &str) -> String { fn build_prompt_gpt_oss(messages: &[Message]) -> String { let mut prompt = String::new(); + // Canonical harmony system message (mirrors the model's chat_template.jinja + // build_system_message macro). A hand-rolled substitute puts gpt-oss out of + // distribution and destabilizes channel selection. This hardcoded builder is + // only a fallback for gpt-oss models that ship no Jinja template; the + // gpt-oss-20b release does ship one, so the template path is normally used. prompt.push_str("<|start|>system<|message|>"); - prompt.push_str("You are a helpful assistant.\n\n# Valid channels: analysis, commentary, final. Channel must be included for every message."); + prompt.push_str("You are ChatGPT, a large language model trained by OpenAI.\n"); + prompt.push_str("Knowledge cutoff: 2024-06\n"); + prompt.push_str(&format!("Current date: {}\n\n", strftime_now("%Y-%m-%d".to_string()))); + prompt.push_str("Reasoning: low\n\n"); + prompt.push_str("# Valid channels: analysis, commentary, final. Channel must be included for every message."); prompt.push_str("<|end|>"); let dev_instructions: String = messages .iter()