Route message-board notifications through agent mailboxes (#59139)

## Why

Board notifications were skipped when recipients had no active turn accepting mailbox delivery. Queue them through the ordinary agent-message path so idle recipients can receive them in a later turn.

## What changed

- Submit board notices as `Op::InterAgentCommunication` with `trigger_turn` disabled, preserving normal mailbox scheduling without reopening finalized answers.
- Hold a residency guard through dispatch of submitted agent messages to coordinate delivery with agent eviction.
- Update board tool descriptions to describe the host's notification queueing and wake policy.

## Testing

Update local and HTTP board scenarios to cover queued idle notices, delivery after a finalized answer, and mailbox delivery before a pending tool call. Extend residency coverage to verify that submission waits for the eviction gate and queued messages survive eviction.

GitOrigin-RevId: a77137fc40932f5903852e14742483844e07c9bc
This commit is contained in:
jif
2026-11-03 12:33:26 +00:00
committed by copyberry
parent 3b5483307d
commit f05aa41da6
16 changed files with 159 additions and 110 deletions
+4 -6
View File
@@ -264,7 +264,7 @@ impl LocalAgentControl {
if owner_thread_id.is_none()
&& let Ok(thread) = state.get_thread(thread_id).await
{
return self.runtime.pin_v2_residency(&state, &thread).await;
return self.runtime.pin_v2_residency(&thread).await;
}
if self
.runtime
@@ -328,7 +328,7 @@ impl LocalAgentControl {
}
if let Ok(thread) = state.get_thread(thread_id).await {
self.validate_loaded_v2_child(&thread, parent_thread_id)?;
return self.runtime.pin_v2_residency(&state, &thread).await;
return self.runtime.pin_v2_residency(&thread).await;
}
}
let parent = if let Some(parent) = parent {
@@ -589,9 +589,7 @@ impl LocalAgentControl {
// Finish registration even if the sender is cancelled while acquiring its pin.
tokio::spawn(async move {
let _membership = membership;
let residency_pin = runtime
.pin_v2_residency(&state, &reloaded_thread.thread)
.await?;
let residency_pin = runtime.pin_v2_residency(&reloaded_thread.thread).await?;
runtime.registry.clear_evicted_environments(thread_id);
residency_slot.commit(reloaded_thread.thread_id);
// Register before listeners can forward events from the resumed thread.
@@ -616,7 +614,7 @@ impl LocalAgentControl {
}
self.runtime.registry.clear_evicted_environments(thread_id);
drop(residency_slot);
return self.runtime.pin_v2_residency(&state, &thread).await;
return self.runtime.pin_v2_residency(&thread).await;
}
Err(err)
}