support developer role in chat completions API (#867)

This commit is contained in:
Adil Hafeez 2026-04-02 18:10:32 -07:00 committed by GitHub
parent 1d3f4d6c05
commit 7606c55b4b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 15 additions and 8 deletions

View file

@ -762,7 +762,7 @@ impl ArchFunctionHandler {
// Keep system message if present
if let Some(first) = messages.first() {
if first.role == Role::System {
if first.role == Role::System || first.role == Role::Developer {
if let Some(MessageContent::Text(content)) = &first.content {
num_tokens += content.len() / 4; // Approximate 4 chars per token
}

View file

@ -183,6 +183,7 @@ impl OrchestratorModel for OrchestratorModelV1 {
.iter()
.filter(|m| {
m.role != Role::System
&& m.role != Role::Developer
&& m.role != Role::Tool
&& !m.content.extract_text().is_empty()
})

View file

@ -80,6 +80,7 @@ impl RouterModel for RouterModelV1 {
.iter()
.filter(|m| {
m.role != Role::System
&& m.role != Role::Developer
&& m.role != Role::Tool
&& !m.content.extract_text().is_empty()
})

View file

@ -572,7 +572,9 @@ impl ProviderRequest for MessagesRequest {
let mut regular_messages = Vec::new();
for msg in messages {
if msg.role == crate::apis::openai::Role::System {
if msg.role == crate::apis::openai::Role::System
|| msg.role == crate::apis::openai::Role::Developer
{
system_messages.push(msg.clone());
} else {
regular_messages.push(msg.clone());

View file

@ -150,6 +150,7 @@ pub enum Role {
User,
Assistant,
Tool,
Developer,
}
#[skip_serializing_none]
@ -736,6 +737,7 @@ impl ProviderStreamResponse for ChatCompletionsStreamResponse {
Role::User => "user",
Role::Assistant => "assistant",
Role::Tool => "tool",
Role::Developer => "developer",
})
})
}

View file

@ -97,7 +97,7 @@ impl TryFrom<ResponsesInputConverter> for Vec<Message> {
MessageRole::User => Role::User,
MessageRole::Assistant => Role::Assistant,
MessageRole::System => Role::System,
MessageRole::Developer => Role::System, // Map developer to system
MessageRole::Developer => Role::Developer,
MessageRole::Tool => Role::Tool,
};
@ -281,7 +281,7 @@ impl TryFrom<Message> for MessagesMessage {
]),
});
}
Role::System => {
Role::System | Role::Developer => {
return Err(TransformError::UnsupportedConversion(
"System messages should be handled separately".to_string(),
));
@ -303,7 +303,7 @@ impl TryFrom<Message> for BedrockMessage {
Role::User => ConversationRole::User,
Role::Assistant => ConversationRole::Assistant,
Role::Tool => ConversationRole::User, // Tool results become user messages in Bedrock
Role::System => {
Role::System | Role::Developer => {
return Err(TransformError::UnsupportedConversion(
"System messages should be handled separately in Bedrock".to_string(),
));
@ -452,7 +452,7 @@ impl TryFrom<Message> for BedrockMessage {
},
});
}
Role::System => {
Role::System | Role::Developer => {
// Already handled above with early return
unreachable!()
}
@ -706,7 +706,7 @@ impl TryFrom<ChatCompletionsRequest> for AnthropicMessagesRequest {
for message in req.messages {
match message.role {
Role::System => {
Role::System | Role::Developer => {
system_prompt = Some(message.into());
}
_ => {
@ -755,7 +755,7 @@ impl TryFrom<ChatCompletionsRequest> for ConverseRequest {
for message in req.messages {
match message.role {
Role::System => {
Role::System | Role::Developer => {
let system_text = message.content.extract_text();
system_messages.push(SystemContentBlock::Text { text: system_text });
}

View file

@ -95,6 +95,7 @@ impl TryFrom<ChatCompletionsResponse> for ResponsesAPIResponse {
Role::Assistant => "assistant".to_string(),
Role::System => "system".to_string(),
Role::Tool => "tool".to_string(),
Role::Developer => "developer".to_string(),
},
content,
});