use super::{Pump, RpcError, Version};
use serde_json::{Value, json};
impl Pump {
pub(super) async fn turn_response(
&mut self,
id: &Value,
result: Result<Value, RpcError>,
) -> anyhow::Result<()> {
anyhow::ensure!(
self.turn
.as_ref()
.is_some_and(|turn| *id == json!(turn.call)),
"acp_response_id_unknown"
);
match result {
Err(error) => {
self.say(json!({"kind":"turn_failed","code":error.code,"message":error.message,
"reason":if error.code==-32000 {"authentication_required"}else{"harness_refused"}})).await?;
self.finished().await
}
Ok(answer) if self.session.version == Version::One => {
let response: agent_client_protocol_schema::v1::PromptResponse =
super::super::handshake::decode(answer, "session_prompt")?;
if let Some(turn) = self.turn.as_mut() {
turn.idle = Some(serde_json::to_value(response.stop_reason)?);
}
self.end_turn().await
}
Ok(answer) => {
super::super::handshake::decode::<agent_client_protocol_schema::v2::PromptResponse>(
answer,
"session_prompt",
)?;
let turn = self
.turn
.as_mut()
.ok_or_else(|| anyhow::anyhow!("turn_absent"))?;
turn.acknowledged = true;
if turn.idle.is_some() {
self.end_turn().await?;
}
Ok(())
}
}
}
pub(super) async fn end_turn(&mut self) -> anyhow::Result<()> {
self.cancel_pending()?;
if !self.answers.is_empty() {
return Ok(());
}
let turn = self
.turn
.as_ref()
.ok_or_else(|| anyhow::anyhow!("turn_absent"))?;
let reason = if turn.cancelled {
json!("cancelled")
} else {
turn.idle.clone().unwrap_or(Value::Null)
};
self.say(json!({"kind":"turn_ended","request_id":turn.request,"stop_reason":reason}))
.await?;
self.finished().await
}
}