void-box logoVoid-Box
Guide

Pipeline Composition

Pipelines chain multiple Boxes into a sequence where the output of one stage becomes the input of the next. Each stage boots a fresh micro-VM, so there are no state leaks between stages.

1. Why pipelines

Running everything in a single agent context means a long-lived VM accumulates side effects: temp files, environment mutations, leaked credentials in memory. Pipelines solve this by giving each stage a clean slate.

2. Simple 2-stage pipeline

The quick_demo.rs example chains an analyst and a strategist:

use void_box::agent_box::VoidBox;
use void_box::pipeline::Pipeline;
use void_box::skill::Skill;

let reasoning = Skill::agent("claude-code");

let analyst = VoidBox::new("analyst")
    .skill(reasoning.clone())
    .prompt("List 3 bullish and 3 bearish signals for AAPL.")
    .build()?;

let strategist = VoidBox::new("strategist")
    .skill(reasoning.clone())
    .prompt("Read /workspace/input.json and produce a BUY/SELL/HOLD verdict.")
    .build()?;

let result = Pipeline::named("quick_demo", analyst)
    .pipe(strategist)
    .run().await?;

3. Fan-out (parallel stages)

Use .fan_out() to run multiple Boxes in parallel. All receive the same input from the previous stage.

let result = Pipeline::named("research", researcher)
    .fan_out(vec![analyst, writer]) // parallel
    .run().await?;

4. Pipeline results API

The PipelineResult returned by .run() gives you structured access to every stage:

println!("Success: {}", result.success());
println!("Cost:    ${:.4}", result.total_cost_usd());
println!("Stages:  {}", result.stages.len());

for stage in &result.stages {
    println!("  {} — {} tokens",
        stage.box_name,
        stage.claude_result.input_tokens + stage.claude_result.output_tokens);
}

5. Next

Define pipelines declaratively with YAML Specs, or run agents with local LLMs via Ollama.