codetether-agent 4.5.7

A2A-native AI coding agent for the CodeTether ecosystem
Documentation
use crate::provider::{ContentPart, Message, Role};
use anyhow::Result;
use serde_json::Value;

use crate::session::codex_import::payloads::CodexResponseMessagePayload;

pub(super) fn parse_message_item(
    payload: Value,
    first_user_text: &mut Option<String>,
) -> Result<Option<Message>> {
    let payload: CodexResponseMessagePayload = serde_json::from_value(payload)?;
    let Some(role) = map_role(&payload.role) else {
        return Ok(None);
    };
    let mut content = Vec::new();

    for item in payload.content {
        match item.kind.as_str() {
            "input_text" | "output_text" => {
                let Some(text) = item.text.map(|value| value.trim().to_string()) else {
                    continue;
                };
                if text.is_empty() {
                    continue;
                }
                if role == Role::User && first_user_text.is_none() {
                    *first_user_text = Some(text.clone());
                }
                content.push(ContentPart::Text { text });
            }
            "input_image" => {
                let Some(url) = item.image_url.filter(|value| !value.is_empty()) else {
                    continue;
                };
                content.push(ContentPart::Image {
                    url,
                    mime_type: None,
                });
            }
            _ => {}
        }
    }

    Ok((!content.is_empty()).then_some(Message { role, content }))
}

fn map_role(role: &str) -> Option<Role> {
    match role {
        "user" => Some(Role::User),
        "assistant" => Some(Role::Assistant),
        _ => None,
    }
}