use std::pin::Pin; use std::task::Context; use std::task::Poll; use codex_protocol::config_types::ReasoningEffort as ReasoningEffortConfig; use codex_protocol::config_types::ReasoningSummary as ReasoningSummaryConfig; use codex_protocol::models::ResponseItem; use codex_protocol::protocol::RateLimitSnapshot; use codex_protocol::protocol::TokenUsage; use futures::Stream; use serde::Serialize; use serde_json::Value; use tokio::sync::mpsc; use crate::error::Result; #[derive(Debug, Serialize, Clone)] pub struct Reasoning { #[serde(skip_serializing_if = "Option::is_none")] pub effort: Option, #[serde(skip_serializing_if = "Option::is_none")] pub summary: Option, } #[derive(Debug, Serialize, Default, Clone)] #[serde(rename_all = "snake_case")] pub enum TextFormatType { #[default] JsonSchema, } #[derive(Debug, Serialize, Default, Clone)] pub struct TextFormat { pub r#type: TextFormatType, pub strict: bool, pub schema: Value, pub name: String, } #[derive(Debug, Serialize, Default, Clone)] pub struct TextControls { #[serde(skip_serializing_if = "Option::is_none")] pub verbosity: Option, #[serde(skip_serializing_if = "Option::is_none")] pub format: Option, } #[derive(Debug)] pub enum ResponseEvent { Created, OutputItemDone(ResponseItem), OutputItemAdded(ResponseItem), Completed { response_id: String, token_usage: Option, }, OutputTextDelta(String), ReasoningSummaryDelta(String), ReasoningContentDelta(String), ReasoningSummaryPartAdded, RateLimits(RateLimitSnapshot), } #[derive(Debug)] pub struct EventStream { pub(crate) rx_event: mpsc::Receiver, } impl EventStream { pub fn from_receiver(rx_event: mpsc::Receiver) -> Self { Self { rx_event } } } impl Stream for EventStream { type Item = T; fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { self.rx_event.poll_recv(cx) } } pub type ResponseStream = EventStream>; pub type WireEvent = ResponseEvent; pub type WireResponseStream = ResponseStream;