use agent_client_protocol::schema::v1::{PromptResponse, StopReason};
use rho_sdk::{model::ContentBlock, CancellationToken, UserInput};
use super::{
super::t3_wake::{Background, PromptOrigin, WakeSignal},
send_notification, EventMapper, SessionHost,
};
use crate::app::acp::AcpClientPort;
const WATCHER_NOTE: &str = "Delegated tasks titled `waiting: ...` are Rho's background-work \
watchers, not agents, and hold no result. Results of background work \
that finished, if any, follow.";
impl SessionHost {
pub(super) fn wake_prompt_started(&mut self, input: &UserInput) -> Option<&'static str> {
let wake = self.t3_wake.as_mut()?;
let text = match input.blocks().first() {
Some(ContentBlock::Text(text)) => Some(text.as_str()),
_ => None,
};
match wake.prompt_started(text) {
PromptOrigin::WatcherNotice => Some(WATCHER_NOTE),
PromptOrigin::Other => None,
}
}
pub(super) async fn wake_prompt_ended(
&mut self,
stop: Option<StopReason>,
client: &dyn AcpClientPort,
) {
let Some(wake) = self.t3_wake.as_mut() else {
return;
};
let background = Background::of(&self.built.tools, self.built.session.id().to_string());
let Err(error) = wake.prompt_ended(&self.built.tools, background).await else {
return;
};
if stop == Some(StopReason::Cancelled) {
tracing::debug!(%error, "could not arm T3 wake watcher after a cancelled prompt");
return;
}
tracing::warn!(%error, "could not arm T3 wake watcher");
let notice = EventMapper::agent_notice(
&self.acp_session_id,
&format!(
"\n\ncould not watch background work: {error}. Its results arrive with your \
next message."
),
);
if let Err(error) = send_notification(client, notice).await {
tracing::debug!(%error, "could not send T3 wake failure notice");
}
}
pub(super) async fn await_wake(
&self,
signal: WakeSignal,
cancel: &CancellationToken,
client: &dyn AcpClientPort,
) -> anyhow::Result<PromptResponse> {
let Some(summary) = signal.wait(cancel).await else {
return Ok(PromptResponse::new(StopReason::Cancelled));
};
send_notification(
client,
EventMapper::agent_notice(&self.acp_session_id, &summary),
)
.await?;
Ok(PromptResponse::new(StopReason::EndTurn))
}
}