Skip to content
Open
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ ignore = "0.4"
rand = "0.9"
iana-time-zone = "0.1"
image = { version = "0.25", default-features = false, features = ["png", "jpeg", "gif", "webp"] }
libc = "0.2"
ratatui = { version = "0.30", default-features = false, features = ["crossterm_0_29"] }
reqwest = { version = "0.12", default-features = false, features = ["blocking", "json", "rustls-tls"] }
regex = "1"
Expand Down
1 change: 1 addition & 0 deletions crates/browser-use-agent/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ rand.workspace = true
regex.workspace = true
reqwest = { workspace = true, features = ["stream"] }
rustls.workspace = true
libc.workspace = true
serde.workspace = true
serde_json.workspace = true
sha2.workspace = true
Expand Down
13 changes: 12 additions & 1 deletion crates/browser-use-agent/src/compact/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,18 @@ pub fn compacted_history_from_summary(
summary_suffix: CompactionSummary,
token_limit: usize,
) -> CompactedHistory {
let summary_text = format!("{SUMMARY_PREFIX}\n{}", summary_suffix.text);
// The empty-summary fallback must apply to the SUFFIX, before the prefix
// is prepended — otherwise the prefix makes the combined string non-empty
// and the fallback in build_compacted_history never fires. A summarize()
// pass that returns no text then ships "...Here is the summary...:" followed
// by NOTHING, leaving the post-compaction model with total amnesia (real_v8
// task 24: 30 thrash turns, task lost).
let suffix_text = if summary_suffix.text.trim().is_empty() {
"(no summary available)".to_string()
} else {
summary_suffix.text.clone()
};
let summary_text = format!("{SUMMARY_PREFIX}\n{suffix_text}");
let user_messages: Vec<String> = history.iter().filter_map(real_user_message_text).collect();
let items = build_compacted_history(&user_messages, &summary_text, token_limit);

Expand Down
15 changes: 9 additions & 6 deletions crates/browser-use-agent/src/compact/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -370,11 +370,11 @@ async fn context_window_exceeded_with_only_prompt_left_propagates() {
}

#[tokio::test]
async fn empty_model_summary_yields_prefix_only_summary() {
// The model returns an empty summary => summary_text = PREFIX + "\n" + "".
// (The "(no summary available)" placeholder only applies when the WHOLE
// summary_text is empty, which it never is here because the prefix is present;
// codex compact.rs:516.)
async fn empty_model_summary_yields_no_summary_available_fallback() {
// The model returns an empty summary => the SUFFIX falls back to
// "(no summary available)" BEFORE the prefix is prepended (codex
// compact.rs:516). Shipping PREFIX+"" gave the post-compaction model
// total amnesia (real_v8 task 24).
let history = vec![user_item("a user message")];
let sampler = ScriptedSampler::new(vec![Ok(String::new())]);

Expand All @@ -390,7 +390,10 @@ async fn empty_model_summary_yields_prefix_only_summary() {

let last = item_text(compacted.items.last().unwrap());
assert_eq!(last, compacted.summary_text);
assert_eq!(compacted.summary_text, format!("{SUMMARY_PREFIX}\n"));
assert_eq!(
compacted.summary_text,
format!("{SUMMARY_PREFIX}\n(no summary available)")
);
}

// ---- (5) end-to-end through the real TurnLoop -----------------------------
Expand Down
Loading
Loading