Skip to content

Commit 2c87f2a

Browse files
committed
fix(translator): reset agent message item after tool updates
1 parent 22f907c commit 2c87f2a

File tree

2 files changed

+86
-0
lines changed

2 files changed

+86
-0
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,6 @@ public/assets/material-icons/
3131

3232
# Nix
3333
result
34+
35+
# Project memory (agent context)
36+
.memory/

src-tauri/src/backend/event_translator.rs

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,11 @@ impl SessionTranslationState {
164164
}
165165
}
166166

167+
fn reset_agent_message_item(&mut self, session_id: &str) {
168+
let turn_state = self.get_turn_state_mut(session_id);
169+
turn_state.agent_message_item_id = None;
170+
}
171+
167172
pub(crate) fn user_message_item(&mut self) -> String {
168173
if let Some(ref id) = self.user_message_item_id {
169174
id.clone()
@@ -529,6 +534,7 @@ fn translate_tool_part(
529534
"item": item
530535
}
531536
}));
537+
state.reset_agent_message_item(thread_id);
532538
}
533539
"error" => {
534540
let error_text = tool_state
@@ -551,6 +557,7 @@ fn translate_tool_part(
551557
"item": item
552558
}
553559
}));
560+
state.reset_agent_message_item(thread_id);
554561
}
555562
_ => {}
556563
}
@@ -1227,6 +1234,82 @@ mod tests {
12271234
assert_eq!(events[0]["params"]["item"]["status"], "completed");
12281235
}
12291236

1237+
#[test]
1238+
fn text_after_tool_completion_uses_new_agent_message_item() {
1239+
let mut state = make_state();
1240+
1241+
let first_text = json!({
1242+
"type": "message.part.updated",
1243+
"properties": {
1244+
"part": {
1245+
"type": "text",
1246+
"id": "part_before_tool",
1247+
"sessionID": "ses_test123"
1248+
},
1249+
"delta": "Before tool call."
1250+
}
1251+
});
1252+
let before_events = translate_sse_event(&first_text, &mut state);
1253+
let before_item_id = before_events[0]["params"]["itemId"]
1254+
.as_str()
1255+
.unwrap()
1256+
.to_string();
1257+
1258+
let tool_running = json!({
1259+
"type": "message.part.updated",
1260+
"properties": {
1261+
"part": {
1262+
"type": "tool",
1263+
"id": "tc_split_1",
1264+
"sessionID": "ses_test123",
1265+
"tool": "bash",
1266+
"state": {
1267+
"status": "running",
1268+
"input": { "command": ["pwd"] }
1269+
}
1270+
}
1271+
}
1272+
});
1273+
translate_sse_event(&tool_running, &mut state);
1274+
1275+
let tool_completed = json!({
1276+
"type": "message.part.updated",
1277+
"properties": {
1278+
"part": {
1279+
"type": "tool",
1280+
"id": "tc_split_1",
1281+
"sessionID": "ses_test123",
1282+
"tool": "bash",
1283+
"state": {
1284+
"status": "completed",
1285+
"input": { "command": ["pwd"] },
1286+
"output": "/Users/jacob"
1287+
}
1288+
}
1289+
}
1290+
});
1291+
translate_sse_event(&tool_completed, &mut state);
1292+
1293+
let second_text = json!({
1294+
"type": "message.part.updated",
1295+
"properties": {
1296+
"part": {
1297+
"type": "text",
1298+
"id": "part_after_tool",
1299+
"sessionID": "ses_test123"
1300+
},
1301+
"delta": "After tool call."
1302+
}
1303+
});
1304+
let after_events = translate_sse_event(&second_text, &mut state);
1305+
let after_item_id = after_events[0]["params"]["itemId"]
1306+
.as_str()
1307+
.unwrap()
1308+
.to_string();
1309+
1310+
assert_ne!(before_item_id, after_item_id);
1311+
}
1312+
12301313
#[test]
12311314
fn message_updated_produces_token_usage() {
12321315
let mut state = make_state();

0 commit comments

Comments
 (0)