vv-agent 0.6.2

VectorVein agent runtime, SDK, CLI, tools, and workspace backends
Documentation
use std::collections::BTreeMap;
use std::path::PathBuf;

use serde_json::{json, Value};

use crate::tools::base::ToolContext;

pub fn to_json(data: &Value) -> String {
    serde_json::to_string(data).unwrap_or_else(|_| "null".to_string())
}

pub fn is_string_keyed_dict(value: &Value) -> bool {
    value.is_object()
}

pub fn get_todo_list(shared_state: &mut BTreeMap<String, Value>) -> &mut Vec<Value> {
    let value = shared_state
        .entry("todo_list".to_string())
        .or_insert_with(|| Value::Array(Vec::new()));
    if !value.is_array() {
        *value = Value::Array(Vec::new());
    }
    match value {
        Value::Array(items) => items,
        _ => unreachable!("todo_list was normalized to an array"),
    }
}

pub fn normalize_todo_items(raw_items: &Value) -> Vec<Value> {
    let Some(items) = raw_items.as_array() else {
        return Vec::new();
    };
    items
        .iter()
        .filter_map(|item| {
            let object = item.as_object()?;
            let title = object
                .get("title")
                .and_then(Value::as_str)
                .unwrap_or_default()
                .trim();
            if title.is_empty() {
                return None;
            }
            Some(json!({
                "title": title,
                "done": object.get("done").is_some_and(value_truthy),
            }))
        })
        .collect()
}

pub fn resolve_workspace_path(context: &ToolContext, raw_path: &str) -> Result<PathBuf, String> {
    context.resolve_workspace_path(raw_path)
}

fn value_truthy(value: &Value) -> bool {
    match value {
        Value::Null => false,
        Value::Bool(value) => *value,
        Value::Number(number) => number.as_f64().is_some_and(|value| value != 0.0),
        Value::String(text) => !text.is_empty(),
        Value::Array(items) => !items.is_empty(),
        Value::Object(object) => !object.is_empty(),
    }
}