OpenHuman Orchestration: Subagent Fleets, Checkpointed Runs, and Reasoning Split

OpenHuman's Rust-native orchestration engine enables parent agents to spawn lightweight subagent fleets that execute in parallel, checkpoint their progress via world-diff uploads, and maintain clean reasoning separation between parent and child processes.

OpenHuman is a Rust-native engine designed to power sophisticated AI-assistant behavior through coordinated multi-agent execution. At the heart of this system lies OpenHuman orchestration, a framework that implements subagent fleets capable of running independent tasks while maintaining durable state through checkpointed runs. This architecture allows complex workloads to be distributed across isolated agent processes that can be monitored, awaited, or fired as background tasks without blocking the main reasoning loop.

Subagent Fleet Architecture

OpenHuman orchestration treats subagents as lightweight, ephemeral processes that inherit configuration from a parent turn but execute within isolated sessions. The parent agent builds a system prompt that defines the subagent's archetype—its name, purpose, workspace access, and available tools—through the render_subagent_system_prompt function in src/openhuman/agent/harness/subagent_runner.rs.

When the parent invokes the spawn_subagent tool implemented in src/openhuman/agent/orchestration/tools/spawn_subagent.rs, the orchestration runtime creates a new session entry in the orchestration store. The subagent then enters its own turn loop, utilizing the same tool-calling infrastructure as standard agents, but isolated to its unique session ID. This design enables true parallelism: the parent continues its own reasoning or pauses via the wait_subagent tool while the fleet member processes independently.

The OpenHuman Orchestration Lifecycle

Understanding the lifecycle requires tracing four distinct phases from initialization to completion.

Spawning and Prompt Generation

The parent turn constructs the subagent’s context in src/openhuman/agent/harness/subagent_runner.rs. This includes serializing the workspace state and injecting the "### SUBAGENT" section that the UI renders as a distinct chat bubble, visually separating parent and child reasoning streams.

Independent Execution

Once spawned, the subagent operates autonomously through the core loop in src/openhuman/agent/harness/subagent_runner.rs. It maintains its own transcript under session_raw/subagent-<id>, tracked via src/openhuman/agent/harness/turn_subagent_usage.rs, ensuring that state mutations do not leak into the parent's context.

Synchronization and Retrieval

Parents integrate results through two primary tools. The wait_subagent tool in src/openhuman/agent/orchestration/tools/wait_subagent.rs blocks execution until the subagent reports Completed or hits a timeout. Alternatively, the read_subagent tool in src/openhuman/agent/orchestration/tools/read_subagent.rs retrieves checkpointed outputs without blocking, useful for polling scenarios.

Background Cleanup

For fire-and-forget operations, the parent spawns the subagent without waiting. The orchestration runtime handles lifecycle management through src/openhuman/agent/orchestration/subagent_control.rs and the background delivery logic in src/openhuman/platform/service/shutdown.rs, automatically persisting final states and cleaning up completed sessions.

Reasoning Split: Isolating Parent and Subagent Logic

OpenHuman orchestration enforces a strict reasoning split that prevents state interleaving. The parent reasoning layer focuses on high-level planning: determining whether to spawn a subagent, constructing its initial prompt, and synthesizing results into the broader conversation flow. This logic remains in the primary session thread.

Conversely, subagent reasoning operates within its own isolated session, receiving a prompt that includes the parent's "workspace soul" and relevant memory snapshots, but executing independently. The separation is explicit in the storage layer—subagent transcripts live under session_raw/subagent-<id>—and in the prompt format, where the "### SUBAGENT" delimiter provides clear cognitive boundaries. This architecture allows the system to reason about parallel task trees without concurrency conflicts.

Checkpointing Runs for Fault Tolerance

Durability is achieved through the world-diff mechanism. Each state transition is checkpointed to the orchestration backend via POST /orchestration/v1/world-diff. The uploader in src/openhuman/hosted/orchestration/world_diff_uploader.rs batches these diffs, implements retry logic with exponential backoff, and logs upload status under the "orchestration" log target.

On process restart, the core re-hydrates the orchestration store from persisted world-diffs, ensuring that subagent progress survives crashes or deployments. This guarantees that long-running background tasks remain intact even when the parent process terminates unexpectedly.

Implementing Subagent Orchestration in Practice

The following examples demonstrate the primary patterns for interacting with the orchestration API.

Synchronous Subagent Execution

Use run_subagent when the parent requires the subagent's output before continuing:

use openhuman_core::openhuman::agent::harness::subagent_runner::run_subagent;
use openhuman_core::openhuman::agent::harness::SubagentRunOptions;

// Load your AgentDefinition from configuration
let def = /* ... load AgentDefinition ... */;

// Execute and await completion
let outcome = run_subagent(&def, "research-task", SubagentRunOptions::default())
    .await
    .expect("subagent execution failed");

println!("Subagent answer: {}", outcome.output);

Source: src/openhuman/agent/harness/subagent_runner.rs (function run_subagent).

Fire-and-Forget Background Tasks

Launch asynchronous work using the spawn tool:

use openhuman_core::openhuman::agent::orchestration::tools::SpawnAsyncSubagent;

let tool = SpawnAsyncSubagent::new(config.clone());
let result = tool.run(/* args with subagent definition */).await?;
println!("Background subagent launched, ID: {}", result.subagent_id);

Source: src/openhuman/agent/orchestration/tools/spawn_async_subagent.rs.

Waiting for Completion

Block until a specific subagent finishes:

use openhuman_core::openhuman::agent::orchestration::tools::WaitSubagent;

let wait = WaitSubagent::new(config.clone());
// Returns status when subagent reaches Completed or timeout
let status = wait.run(subagent_id).await?;
println!("Subagent {} status: {}", subagent_id, status);

Source: src/openhuman/agent/orchestration/tools/wait_subagent.rs.

Monitoring Active Fleets

List currently running subagents:

use openhuman_core::openhuman::agent::orchestration::tools::ListSubagents;

let list = ListSubagents::new(config.clone()).run(()).await?;
println!("Active subagents: {:?}", list.subagents);

Source: src/openhuman/agent/orchestration/tools/list_subagents.rs.

Key Source Files for OpenHuman Orchestration

The implementation spans the agent harness, orchestration domain, and platform service layers:

Summary

  • OpenHuman orchestration enables parent agents to delegate work to isolated subagent fleets that run in parallel without blocking the main reasoning thread.
  • The reasoning split maintains clean separation between parent planning logic and subagent execution, with transcripts stored under isolated session paths like session_raw/subagent-<id>.
  • Checkpointed runs persist state via the world-diff mechanism in world_diff_uploader.rs, ensuring durability across process restarts through POST /orchestration/v1/world-diff batch uploads.
  • Developers can spawn subagents synchronously via run_subagent, asynchronously via SpawnAsyncSubagent, or query status through ListSubagents and WaitSubagent tools.
  • The orchestration domain in src/openhuman/hosted/orchestration/ coordinates persistence, while subagent_control.rs handles runtime lifecycle management.

Frequently Asked Questions

What is a subagent fleet in OpenHuman?

A subagent fleet is a collection of lightweight agent processes spawned by a parent turn to handle parallel or long-running tasks. Each member operates within its own isolated session, defined by an archetype specifying its purpose, tools, and workspace access, allowing the main agent to distribute cognitive load across multiple independent reasoning contexts.

How does OpenHuman checkpoint subagent progress?

The system checkpoints progress through the world-diff uploader in src/openhuman/hosted/orchestration/world_diff_uploader.rs, which batches state changes and transmits them to POST /orchestration/v1/world-diff. On failure, it retries with backoff, logging to the "orchestration" target. If the core restarts, it re-hydrates the orchestration store from these persisted diffs, restoring subagent transcripts exactly where they left off.

What is the reasoning split between parent and subagent?

The reasoning split is an architectural boundary where the parent agent handles high-level orchestration decisions—such as whether to spawn help and how to integrate results—while the subagent performs isolated task execution within its own session. The parent writes subagent prompts containing a "### SUBAGENT" section, and the subagent's reasoning is stored separately under session_raw/subagent-<id>, preventing state pollution between the two contexts.

How do I spawn a background subagent without blocking the parent?

Use the SpawnAsyncSubagent tool from src/openhuman/agent/orchestration/tools/spawn_async_subagent.rs. This registers the subagent with the orchestration store and returns immediately with a subagent_id, allowing the parent to continue processing. The runtime automatically manages the subagent lifecycle and cleanup through subagent_control.rs without requiring the parent to await completion.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →