server: emit harmony developer instructions block for gpt-oss

Route caller-supplied system messages into a harmony 'developer'
instructions block (<|start|>developer<|message|># Instructions...),
keeping the fixed system/meta block for the channel declaration. Harmony
puts user instructions on the developer role, not system.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-05-31 00:56:39 +08:00
parent 3c9d5e260e
commit ffd90ce7fb

View File

@@ -350,10 +350,23 @@ fn build_prompt(messages: &[Message], model_type: &str) -> String {
fn build_prompt_gpt_oss(messages: &[Message]) -> String { fn build_prompt_gpt_oss(messages: &[Message]) -> String {
let mut prompt = String::new(); let mut prompt = String::new();
// System prompt // System (meta) block: channel declaration required by harmony.
prompt.push_str("<|start|>system<|message|>"); 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 a helpful assistant.\n\n# Valid channels: analysis, commentary, final. Channel must be included for every message.");
prompt.push_str("<|end|>"); prompt.push_str("<|end|>");
// Caller-supplied system prompt(s) go in a developer instructions block
// (harmony puts user instructions on the `developer` role, not `system`).
let dev_instructions: String = messages
.iter()
.filter(|m| m.role == "system")
.map(|m| m.content.as_str())
.collect::<Vec<_>>()
.join("\n\n");
if !dev_instructions.is_empty() {
prompt.push_str("<|start|>developer<|message|># Instructions\n\n");
prompt.push_str(&dev_instructions);
prompt.push_str("<|end|>");
}
for msg in messages { for msg in messages {
match msg.role.as_str() { match msg.role.as_str() {
"user" => { "user" => {