haematite-cli 0.21.1

The haematite command: serve a store, its door and Studio, answer MCP, query with jq, and host the store's assistant seat
Documentation
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
    }
}