Skip to content

Commit e807863

Browse files
Merge pull request #2065 from codestoryai/fix-undo-redo
Truncate hidden messages during undo/redo
2 parents 0f7bae0 + a08c24d commit e807863

File tree

2 files changed

+60
-22
lines changed

2 files changed

+60
-22
lines changed

sidecar/src/agentic/tool/session/service.rs

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,9 @@ impl SessionService {
146146

147147
println!("session_service::session_created");
148148

149+
// truncate hidden messages
150+
session.truncate_hidden_exchanges();
151+
149152
// add human message
150153
session = session.human_message(
151154
exchange_id.to_owned(),
@@ -227,6 +230,10 @@ impl SessionService {
227230
user_context.clone(),
228231
)
229232
};
233+
234+
// truncate hidden messages
235+
session.truncate_hidden_exchanges();
236+
230237
// One trick over here which we can do for now is keep track of the
231238
// exchange which we are going to reply to this way we make sure
232239
// that we are able to get the right exchange properly
@@ -324,6 +331,9 @@ impl SessionService {
324331
)
325332
};
326333

334+
// truncate hidden messages
335+
session.truncate_hidden_exchanges();
336+
327337
// add an exchange that we are going to genrate a plan over here
328338
session = session.plan(exchange_id.to_owned(), query, user_context);
329339
self.save_to_storage(&session, None).await?;
@@ -450,6 +460,9 @@ impl SessionService {
450460
.collect(),
451461
);
452462

463+
// truncate hidden messages
464+
session.truncate_hidden_exchanges();
465+
453466
let tool_agent = ToolUseAgent::new(
454467
llm_broker.clone(),
455468
root_directory.to_owned(),
@@ -895,6 +908,9 @@ impl SessionService {
895908
)
896909
};
897910

911+
// truncate hidden messages
912+
session.truncate_hidden_exchanges();
913+
898914
// add an exchange that we are going to perform anchored edits
899915
session = session.agentic_edit(exchange_id, edit_request, user_context, codebase_search);
900916

@@ -958,6 +974,9 @@ impl SessionService {
958974
)
959975
};
960976

977+
// truncate hidden messages
978+
session.truncate_hidden_exchanges();
979+
961980
let selection_variable = user_context.variables.iter().find(|variable| {
962981
variable.is_selection()
963982
&& !(variable.start_position.line() == 0 && variable.end_position.line() == 0)
@@ -1048,10 +1067,10 @@ impl SessionService {
10481067
return Ok(());
10491068
}
10501069
let mut session = session_maybe.expect("is_err to hold");
1051-
1070+
10521071
// Mark exchanges as deleted or not deleted based on the checkpoint
10531072
session = session.move_to_checkpoint(exchange_id).await?;
1054-
1073+
10551074
self.save_to_storage(&session, None).await?;
10561075
Ok(())
10571076
}
@@ -1194,15 +1213,15 @@ impl SessionService {
11941213

11951214
// Trim the content to handle any potential trailing whitespace
11961215
let trimmed_content = content.trim();
1197-
1216+
11981217
let session: Session = serde_json::from_str(trimmed_content)
11991218
.map_err(|e| {
12001219
SymbolError::IOError(std::io::Error::new(
12011220
std::io::ErrorKind::InvalidData,
12021221
format!("Error deserializing session: {}: {}", storage_path, e),
12031222
))
12041223
})?;
1205-
1224+
12061225
Ok(session)
12071226
}
12081227

sidecar/src/agentic/tool/session/session.rs

Lines changed: 37 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,12 @@ pub struct Exchange {
316316
/// stays smallish and nimble
317317
#[serde(default)]
318318
is_compressed: bool,
319+
/// is_hidden implies that the user has been going through the undo/redo
320+
/// motions, and the exchanges that are undone are marked as hidden.
321+
/// Importantly, when the user sends a new message with some hidden messages,
322+
/// they get permanently truncated.
323+
#[serde(default)]
324+
is_hidden: bool,
319325
}
320326

321327
impl Exchange {
@@ -340,6 +346,7 @@ impl Exchange {
340346
)),
341347
exchange_state: ExchangeState::UserMessage,
342348
is_compressed: false,
349+
is_hidden: false,
343350
}
344351
}
345352

@@ -353,6 +360,7 @@ impl Exchange {
353360
}),
354361
exchange_state: ExchangeState::UserMessage,
355362
is_compressed: false,
363+
is_hidden: false,
356364
}
357365
}
358366

@@ -374,6 +382,7 @@ impl Exchange {
374382
}),
375383
exchange_state: ExchangeState::UserMessage,
376384
is_compressed: false,
385+
is_hidden: false,
377386
}
378387
}
379388

@@ -399,6 +408,7 @@ impl Exchange {
399408
}),
400409
exchange_state: ExchangeState::UserMessage,
401410
is_compressed: false,
411+
is_hidden: false,
402412
}
403413
}
404414

@@ -411,6 +421,7 @@ impl Exchange {
411421
)),
412422
exchange_state: ExchangeState::Running,
413423
is_compressed: false,
424+
is_hidden: false,
414425
}
415426
}
416427

@@ -423,6 +434,7 @@ impl Exchange {
423434
)),
424435
exchange_state: ExchangeState::Running,
425436
is_compressed: false,
437+
is_hidden: false,
426438
}
427439
}
428440

@@ -439,6 +451,7 @@ impl Exchange {
439451
)),
440452
exchange_state: ExchangeState::Running,
441453
is_compressed: false,
454+
is_hidden: false,
442455
}
443456
}
444457

@@ -461,6 +474,7 @@ impl Exchange {
461474
)),
462475
exchange_state: ExchangeState::Running,
463476
is_compressed: false,
477+
is_hidden: false,
464478
}
465479
}
466480

@@ -482,6 +496,7 @@ impl Exchange {
482496
)),
483497
exchange_state: ExchangeState::Running,
484498
is_compressed: false,
499+
is_hidden: false,
485500
}
486501
}
487502

@@ -525,7 +540,7 @@ impl Exchange {
525540
/// We can have consecutive human messages now on every API so this is no
526541
/// longer a big worry
527542
async fn to_conversation_message(&self, is_json_mode: bool) -> Option<SessionChatMessage> {
528-
if self.is_compressed {
543+
if self.is_compressed || self.is_hidden {
529544
return None;
530545
}
531546
let session_chat_message = match &self.exchange_type {
@@ -852,14 +867,6 @@ impl Session {
852867
self.exchanges.len()
853868
}
854869

855-
pub fn exchanges_not_compressed(&self) -> usize {
856-
self.exchanges
857-
.iter()
858-
.filter(|exchange| !exchange.is_compressed)
859-
.collect::<Vec<_>>()
860-
.len()
861-
}
862-
863870
fn find_exchange_by_id(&self, exchange_id: &str) -> Option<&Exchange> {
864871
self.exchanges
865872
.iter()
@@ -1099,20 +1106,20 @@ impl Session {
10991106
) -> Result<Self, SymbolError> {
11001107
// Find the index of the target exchange
11011108
let target_index = self.exchanges.iter().position(|exchange| &exchange.exchange_id == exchange_id);
1102-
1109+
11031110
if let Some(target_index) = target_index {
1104-
// Mark exchanges as compressed (deleted) or not compressed based on the checkpoint
1111+
// Mark exchanges based on their position relative to the checkpoint
11051112
for (i, exchange) in self.exchanges.iter_mut().enumerate() {
1106-
if i <= target_index {
1107-
// Exchanges up to and including the target are not compressed
1108-
exchange.is_compressed = false;
1113+
// If target_index is 0, we want to compress it and everything after
1114+
// Otherwise, we only want to compress everything after the target_index
1115+
let will_compress = if target_index == 0 {
1116+
i >= target_index
11091117
} else {
1110-
// Exchanges after the target are compressed (deleted)
1111-
exchange.is_compressed = true;
1112-
}
1118+
i > target_index
1119+
};
1120+
exchange.is_hidden = will_compress;
11131121
}
11141122
}
1115-
11161123
Ok(self)
11171124
}
11181125

@@ -1170,6 +1177,7 @@ impl Session {
11701177
}),
11711178
exchange_state: exchange.exchange_state,
11721179
is_compressed: exchange.is_compressed,
1180+
is_hidden: exchange.is_hidden,
11731181
}
11741182
}
11751183
_ => exchange,
@@ -1739,6 +1747,7 @@ impl Session {
17391747
}),
17401748
exchange_state: _,
17411749
is_compressed: _,
1750+
is_hidden: _,
17421751
}) = exchange_in_focus
17431752
else {
17441753
return Ok(self);
@@ -2031,6 +2040,7 @@ impl Session {
20312040
}),
20322041
exchange_state: _,
20332042
is_compressed: _,
2043+
is_hidden: _,
20342044
}) = last_exchange
20352045
{
20362046
let edits_performed = scratch_pad_agent
@@ -2080,6 +2090,7 @@ impl Session {
20802090
}),
20812091
exchange_state: _,
20822092
is_compressed: _,
2093+
is_hidden: _,
20832094
}) = last_exchange
20842095
{
20852096
let mut converted_messages = vec![];
@@ -2188,6 +2199,7 @@ impl Session {
21882199
}),
21892200
exchange_state: _,
21902201
is_compressed: _,
2202+
is_hidden: _,
21912203
}) => {
21922204
// do something over here
21932205
let files_to_edit = plan_steps
@@ -2223,6 +2235,7 @@ impl Session {
22232235
}),
22242236
exchange_state: _,
22252237
is_compressed: _,
2238+
is_hidden: _,
22262239
} => {
22272240
vec![fs_file_path.to_owned()]
22282241
}
@@ -2351,6 +2364,12 @@ impl Session {
23512364
Ok(())
23522365
}
23532366

2367+
pub fn truncate_hidden_exchanges(&mut self) {
2368+
println!("session::truncate_hidden_exchanges::before({})", self.exchanges.len());
2369+
self.exchanges.retain(|exchange| !exchange.is_hidden);
2370+
println!("session::truncate_hidden_exchanges::after({})", self.exchanges.len());
2371+
}
2372+
23542373
pub fn has_running_code_edits(&self, exchange_id: &str) -> bool {
23552374
let found_exchange = self.find_exchange_by_id(exchange_id);
23562375
match found_exchange {

0 commit comments

Comments
 (0)