feat: weak companion progress notify

This commit is contained in:
2026-06-13 00:18:41 +09:00
parent 05fe1f6fb3
commit a87d315471
5 changed files with 562 additions and 20 deletions
+58
View File
@@ -1025,6 +1025,7 @@ async fn notify_while_idle_auto_starts_turn_and_injects_system_message() {
handle
.send(Method::Notify {
message: "turn finished".into(),
auto_run: true,
})
.await
.unwrap();
@@ -1105,6 +1106,62 @@ async fn notify_while_idle_auto_starts_turn_and_injects_system_message() {
);
}
#[tokio::test]
async fn notify_while_idle_with_auto_run_false_waits_for_explicit_run() {
let client = MockClient::new(simple_text_events());
let client_for_assert = client.clone();
let pod = make_pod(client).await;
let handle = spawn_controller(pod).await;
handle
.send(Method::Notify {
message: "progress snapshot".into(),
auto_run: false,
})
.await
.unwrap();
tokio::time::sleep(std::time::Duration::from_millis(100)).await;
assert_eq!(handle.shared_state.get_status(), PodStatus::Idle);
assert!(
client_for_assert.captured_requests().is_empty(),
"weak Notify must not stage RunForNotification while idle"
);
handle.send(Method::run_text("continue")).await.unwrap();
let deadline = tokio::time::Instant::now() + std::time::Duration::from_secs(2);
loop {
if !client_for_assert.captured_requests().is_empty() {
break;
}
assert!(
tokio::time::Instant::now() < deadline,
"explicit run did not reach the mock LLM"
);
tokio::time::sleep(std::time::Duration::from_millis(10)).await;
}
wait_for_status(&handle, PodStatus::Idle).await;
let requests = client_for_assert.captured_requests();
assert_eq!(
requests.len(),
1,
"explicit run should drain the queued notification"
);
let notify_in_request = requests[0].items.iter().any(|i| {
i.as_text()
.is_some_and(|t| t.contains("[Notification]") && t.contains("progress snapshot"))
});
assert!(
notify_in_request,
"queued weak notification must be history-backed on the next explicit run; got items: {:?}",
requests[0]
.items
.iter()
.filter_map(|i| i.as_text())
.collect::<Vec<_>>()
);
}
#[tokio::test]
async fn pod_event_turn_ended_while_idle_auto_starts_turn_and_injects_system_message() {
let client = MockClient::new(simple_text_events());
@@ -1259,6 +1316,7 @@ async fn notify_while_running_does_not_emit_already_running_error() {
handle
.send(Method::Notify {
message: "ping".into(),
auto_run: true,
})
.await
.unwrap();