use serde::Deserialize;
use serde::Serialize;
use crate::payload::RawPayloadId;
use super::AgentPath;
use super::AgentThreadId;
use super::CodeCellId;
use super::CodexTurnId;
use super::CompactionId;
use super::ConversationItemId;
use super::EdgeId;
use super::InferenceCallId;
use super::ModelVisibleCallId;
use super::ToolCallId;
use super::session::ExecutionWindow;
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct ConversationItem {
pub item_id: ConversationItemId,
pub thread_id: AgentThreadId,
pub codex_turn_id: Option<CodexTurnId>,
pub first_seen_at_unix_ms: i64,
pub role: ConversationRole,
pub channel: Option<ConversationChannel>,
pub kind: ConversationItemKind,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub agent_message: Option<AgentMessageMetadata>,
pub body: ConversationBody,
pub call_id: Option<ModelVisibleCallId>,
pub produced_by: Vec<ProducerRef>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct AgentMessageMetadata {
pub author: AgentPath,
pub recipient: AgentPath,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ConversationRole {
System,
Developer,
User,
Assistant,
Tool,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ConversationChannel {
Analysis,
Commentary,
Final,
Summary,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ConversationItemKind {
Message,
Reasoning,
FunctionCall,
FunctionCallOutput,
CustomToolCall,
CustomToolCallOutput,
CompactionMarker,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct ConversationBody {
pub parts: Vec<ConversationPart>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case", tag = "type")]
pub enum ConversationPart {
Text {
text: String,
},
Summary {
text: String,
},
Encoded {
label: String,
value: String,
},
Json {
summary: String,
raw_payload_id: RawPayloadId,
},
Code {
language: String,
source: String,
},
PayloadRef {
label: String,
raw_payload_id: RawPayloadId,
},
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case", tag = "type")]
pub enum ProducerRef {
UserInput,
Inference { inference_call_id: InferenceCallId },
Tool { tool_call_id: ToolCallId },
CodeCell { code_cell_id: CodeCellId },
InteractionEdge { edge_id: EdgeId },
Compaction { compaction_id: CompactionId },
Harness,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct InferenceCall {
pub inference_call_id: InferenceCallId,
pub thread_id: AgentThreadId,
pub codex_turn_id: CodexTurnId,
pub execution: ExecutionWindow,
pub model: String,
pub provider_name: String,
pub response_id: Option<String>,
pub upstream_request_id: Option<String>,
pub request_item_ids: Vec<ConversationItemId>,
pub response_item_ids: Vec<ConversationItemId>,
pub tool_call_ids_started_by_response: Vec<ToolCallId>,
pub usage: Option<TokenUsage>,
pub raw_request_payload_id: RawPayloadId,
pub raw_response_payload_id: Option<RawPayloadId>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct TokenUsage {
pub input_tokens: u64,
pub cached_input_tokens: u64,
#[serde(default)]
pub cache_write_input_tokens: u64,
pub output_tokens: u64,
pub reasoning_output_tokens: u64,
}