systemprompt-agent 0.2.0

Core Agent protocol module for systemprompt.io
Documentation
use crate::error::ArtifactError;
use crate::models::a2a::{DataPart, FileContent, FilePart, Part, TextPart};
use serde_json::Value as JsonValue;

pub fn build_parts(artifact: &JsonValue) -> Result<Vec<Part>, ArtifactError> {
    let mut parts = Vec::new();

    if let Some(obj) = artifact.as_object() {
        parts.push(Part::Data(DataPart { data: obj.clone() }));
        return Ok(parts);
    }

    if let Some(content) = artifact.get("content") {
        if let Some(arr) = content.as_array() {
            for item in arr {
                if let Some(content_type) = item.get("type").and_then(|t| t.as_str()) {
                    match content_type {
                        "text" => {
                            if let Some(text) = item.get("text").and_then(|t| t.as_str()) {
                                parts.push(Part::Text(TextPart {
                                    text: text.to_string(),
                                }));
                            }
                        },
                        "image" => {
                            if let Some(data) = item.get("data").and_then(|d| d.as_str()) {
                                let mime_type = item
                                    .get("mimeType")
                                    .and_then(|m| m.as_str())
                                    .map(ToString::to_string);

                                parts.push(Part::File(FilePart {
                                    file: FileContent {
                                        bytes: Some(data.to_string()),
                                        mime_type,
                                        name: None,
                                        url: None,
                                    },
                                }));
                            }
                        },
                        "resource" => {
                            if let Some(uri) = item.get("uri").and_then(|u| u.as_str()) {
                                let mime_type = item
                                    .get("mimeType")
                                    .and_then(|m| m.as_str())
                                    .map(ToString::to_string);

                                parts.push(Part::File(FilePart {
                                    file: FileContent {
                                        name: Some(uri.to_string()),
                                        mime_type,
                                        bytes: None,
                                        url: None,
                                    },
                                }));
                            }
                        },
                        _ => {},
                    }
                }
            }
            if !parts.is_empty() {
                return Ok(parts);
            }
        }
    }

    Err(ArtifactError::Transform(format!(
        "Artifact must be an object or contain a 'content' array. Received: {}",
        serde_json::to_string_pretty(artifact).unwrap_or_else(|_| "invalid JSON".to_string())
    )))
}