agent: Preserve thinking blocks between requests (#29055)

Looks like the required backend component of this was deployed.

https://github.com/zed-industries/monorepo/actions/runs/14541199197

Release Notes:

- N/A

---------

Co-authored-by: Antonio Scandurra <me@as-cii.com>
Co-authored-by: Agus Zubiaga <hi@aguz.me>
Co-authored-by: Richard Feldman <oss@rtfeldman.com>
Co-authored-by: Nathan Sobo <nathan@zed.dev>
This commit is contained in:
Bennet Bo Fenner 2025-04-19 22:12:03 +02:00 committed by GitHub
parent f737c4d01e
commit bafc086d27
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 236 additions and 68 deletions

View file

@ -65,9 +65,14 @@ pub struct LanguageModelCacheConfiguration {
pub enum LanguageModelCompletionEvent {
Stop(StopReason),
Text(String),
Thinking(String),
Thinking {
text: String,
signature: Option<String>,
},
ToolUse(LanguageModelToolUse),
StartMessage { message_id: String },
StartMessage {
message_id: String,
},
UsageUpdate(TokenUsage),
}
@ -302,7 +307,7 @@ pub trait LanguageModel: Send + Sync {
match result {
Ok(LanguageModelCompletionEvent::StartMessage { .. }) => None,
Ok(LanguageModelCompletionEvent::Text(text)) => Some(Ok(text)),
Ok(LanguageModelCompletionEvent::Thinking(_)) => None,
Ok(LanguageModelCompletionEvent::Thinking { .. }) => None,
Ok(LanguageModelCompletionEvent::Stop(_)) => None,
Ok(LanguageModelCompletionEvent::ToolUse(_)) => None,
Ok(LanguageModelCompletionEvent::UsageUpdate(token_usage)) => {

View file

@ -175,6 +175,11 @@ pub struct LanguageModelToolResult {
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, Hash)]
pub enum MessageContent {
Text(String),
Thinking {
text: String,
signature: Option<String>,
},
RedactedThinking(Vec<u8>),
Image(LanguageModelImage),
ToolUse(LanguageModelToolUse),
ToolResult(LanguageModelToolResult),
@ -204,6 +209,8 @@ impl LanguageModelRequestMessage {
let mut buffer = String::new();
for string in self.content.iter().filter_map(|content| match content {
MessageContent::Text(text) => Some(text.as_str()),
MessageContent::Thinking { text, .. } => Some(text.as_str()),
MessageContent::RedactedThinking(_) => None,
MessageContent::ToolResult(tool_result) => Some(tool_result.content.as_ref()),
MessageContent::ToolUse(_) | MessageContent::Image(_) => None,
}) {
@ -220,10 +227,15 @@ impl LanguageModelRequestMessage {
.first()
.map(|content| match content {
MessageContent::Text(text) => text.chars().all(|c| c.is_whitespace()),
MessageContent::Thinking { text, .. } => {
text.chars().all(|c| c.is_whitespace())
}
MessageContent::ToolResult(tool_result) => {
tool_result.content.chars().all(|c| c.is_whitespace())
}
MessageContent::ToolUse(_) | MessageContent::Image(_) => true,
MessageContent::RedactedThinking(_)
| MessageContent::ToolUse(_)
| MessageContent::Image(_) => true,
})
.unwrap_or(false)
}