Sanitize messages before sending them to Anthropic (#11810)
Antonio Scandurra
,
Nathan
, and
David
created
Release Notes:
- N/A
Co-authored-by: Nathan <nathan@zed.dev>
Co-authored-by: David <davidsp@anthropic.com>
Change summary
crates/anthropic/src/anthropic.rs | 6
crates/assistant/src/completion_provider/anthropic.rs | 54 +++++++-----
2 files changed, 35 insertions(+), 25 deletions(-)
Detailed changes
@@ -11,11 +11,11 @@ pub const ANTHROPIC_API_URL: &'static str = "https://api.anthropic.com";
#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq)]
pub enum Model {
#[default]
- #[serde(rename = "claude-3-opus", alias = "claude-3-opus-20240229")]
+ #[serde(alias = "claude-3-opus", rename = "claude-3-opus-20240229")]
Claude3Opus,
- #[serde(rename = "claude-3-sonnet", alias = "claude-3-sonnet-20240229")]
+ #[serde(alias = "claude-3-sonnet", rename = "claude-3-sonnet-20240229")]
Claude3Sonnet,
- #[serde(rename = "claude-3-haiku", alias = "claude-3-haiku-20240307")]
+ #[serde(alias = "claude-3-haiku", rename = "claude-3-haiku-20240307")]
Claude3Haiku,
}
@@ -169,32 +169,42 @@ impl AnthropicCompletionProvider {
};
let mut system_message = String::new();
- let messages = request
- .messages
- .into_iter()
- .filter_map(|message| {
- match message.role {
- Role::User => Some(RequestMessage {
- role: AnthropicRole::User,
- content: message.content,
- }),
- Role::Assistant => Some(RequestMessage {
- role: AnthropicRole::Assistant,
- content: message.content,
- }),
- // Anthropic's API breaks system instructions out as a separate field rather
- // than having a system message role.
- Role::System => {
- if !system_message.is_empty() {
- system_message.push_str("\n\n");
+
+ let mut messages: Vec<RequestMessage> = Vec::new();
+ for message in request.messages {
+ if message.content.is_empty() {
+ continue;
+ }
+
+ match message.role {
+ Role::User | Role::Assistant => {
+ let role = match message.role {
+ Role::User => AnthropicRole::User,
+ Role::Assistant => AnthropicRole::Assistant,
+ _ => unreachable!(),
+ };
+
+ if let Some(last_message) = messages.last_mut() {
+ if last_message.role == role {
+ last_message.content.push_str("\n\n");
+ last_message.content.push_str(&message.content);
+ continue;
}
- system_message.push_str(&message.content);
+ }
- None
+ messages.push(RequestMessage {
+ role,
+ content: message.content,
+ });
+ }
+ Role::System => {
+ if !system_message.is_empty() {
+ system_message.push_str("\n\n");
}
+ system_message.push_str(&message.content);
}
- })
- .collect();
+ }
+ }
Request {
model,