vv-agent 0.6.2

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

use serde_json::{json, Value};

use crate::tools::base::{SubTaskRunner, ToolContext};
use crate::types::{AgentStatus, SubTaskRequest, ToolExecutionResult};

use super::request::BatchRequestEntry;
use super::response;

pub(super) fn run_batch_sync(
    context: &mut ToolContext,
    runner: SubTaskRunner,
    total: usize,
    entries: Vec<BatchRequestEntry>,
) -> ToolExecutionResult {
    let mut prepared_requests = Vec::new();
    let mut invalid_results = BTreeMap::new();
    for entry in entries {
        if let Some(request) = entry.request {
            prepared_requests.push((entry.index, request));
        } else {
            invalid_results.insert(
                entry.index,
                json!({
                    "index": entry.index,
                    "status": "failed",
                    "error": entry.error.unwrap_or_else(|| "Invalid task item".to_string()),
                }),
            );
        }
    }

    let outcomes = run_prepared_requests(context, runner, prepared_requests);
    let outcome_map: BTreeMap<_, _> = outcomes.into_iter().collect();
    let mut results = Vec::new();
    let mut completed = 0usize;
    let mut failed = 0usize;
    for index in 0..total {
        if let Some(payload) = invalid_results.remove(&index) {
            failed += 1;
            results.push(payload);
            continue;
        }
        let outcome = outcome_map
            .get(&index)
            .expect("valid sub-task request should have an outcome");
        if outcome.status == AgentStatus::Completed {
            completed += 1;
        } else {
            failed += 1;
        }
        let mut payload = outcome.to_value();
        payload["index"] = Value::Number((index as u64).into());
        results.push(payload);
    }

    let payload = json!({
        "summary": {
            "total": total,
            "completed": completed,
            "failed": failed,
        },
        "results": results,
        "wait_for_completion": true,
    });
    if completed == 0 {
        return response::all_batch_tasks_failed(payload);
    }
    response::success(payload)
}

fn run_prepared_requests(
    context: &mut ToolContext,
    runner: SubTaskRunner,
    prepared_requests: Vec<(usize, SubTaskRequest)>,
) -> Vec<(usize, crate::types::SubTaskOutcome)> {
    if let Some(backend) = context.execution_backend.clone() {
        let runner = runner.clone();
        backend.parallel_map(
            move |(index, request)| (index, runner(request)),
            prepared_requests,
        )
    } else {
        prepared_requests
            .into_iter()
            .map(|(index, request)| (index, runner(request)))
            .collect()
    }
}