vv-agent 0.4.7

VectorVein agent runtime, SDK, CLI, tools, and workspace backends
Documentation
use serde_json::Value;

pub(super) fn cache_content_to_vv_llm_content(content: &Value) -> Vec<vv_llm::MessageContent> {
    match content {
        Value::Array(items) => items
            .iter()
            .filter_map(cache_block_to_vv_llm_content)
            .collect(),
        Value::String(text) => vec![vv_llm::MessageContent::text(text.clone())],
        _ => Vec::new(),
    }
}

fn cache_block_to_vv_llm_content(block: &Value) -> Option<vv_llm::MessageContent> {
    let object = block.as_object()?;
    let block_type = object
        .get("type")
        .and_then(Value::as_str)
        .unwrap_or("text")
        .to_ascii_lowercase();
    match block_type.as_str() {
        "text" => Some(vv_llm_text_content_from_cache_block(object)),
        "image_url" => object
            .get("image_url")
            .and_then(|image_url| image_url.get("url"))
            .and_then(Value::as_str)
            .map(|url| vv_llm::MessageContent::ImageUrl {
                url: url.to_string(),
            }),
        "tool_result" => {
            let text = cache_block_content_text(object.get("content"));
            Some(vv_llm_text_content_with_optional_cache_control(
                text,
                object.get("cache_control").cloned(),
            ))
        }
        _ => None,
    }
}

fn vv_llm_text_content_from_cache_block(
    object: &serde_json::Map<String, Value>,
) -> vv_llm::MessageContent {
    let text = object
        .get("text")
        .and_then(Value::as_str)
        .unwrap_or_default()
        .to_string();
    vv_llm_text_content_with_optional_cache_control(text, object.get("cache_control").cloned())
}

fn vv_llm_text_content_with_optional_cache_control(
    text: String,
    cache_control: Option<Value>,
) -> vv_llm::MessageContent {
    match cache_control {
        Some(cache_control) => vv_llm::MessageContent::text_with_cache_control(text, cache_control),
        None => vv_llm::MessageContent::text(text),
    }
}

fn cache_block_content_text(content: Option<&Value>) -> String {
    match content {
        Some(Value::String(text)) => text.clone(),
        Some(Value::Array(_)) | Some(Value::Object(_)) => {
            serde_json::to_string(content.unwrap()).unwrap_or_default()
        }
        Some(Value::Bool(value)) => value.to_string(),
        Some(Value::Number(value)) => value.to_string(),
        Some(Value::Null) | None => String::new(),
    }
}