How OpenHuman CoreBuilder Composes a Runtime from ServiceSet, DomainSet, and ToolGroups

OpenHuman's CoreBuilder creates a CoreRuntime by independently configuring three axes—ServiceSet for background services, DomainSet for domain families, and ToolGroups for tool visibility—then materializing the runtime through the build() method.

The OpenHuman project provides a modular AI core that embedders can configure for diverse environments ranging from full desktop applications to headless libraries. At the heart of this flexibility lies the CoreBuilder API, which orchestrates runtime composition through declarative selection of services, domains, and tools. Understanding how these three independent axes interact allows developers to create precisely tailored runtimes using the tinyhumansai/openhuman codebase.

The Three Axes of Runtime Composition

The CoreBuilder defined in src/core/runtime/builder.rs treats runtime composition as three orthogonal concerns. Each axis can be configured independently, allowing combinations like full domains with no services, or minimal domains with full background infrastructure.

ServiceSet – Background Service Selection

ServiceSet determines which background processes run during the CoreRuntime lifecycle. According to the source code in src/core/runtime/builder.rs at lines 35-39, this includes transport listeners, periodic jobs, cron schedulers, and socket servers.

Common configurations include:

  • ServiceSet::desktop() – Full desktop stack including Tauri UI integration and socket listeners
  • ServiceSet::headless_api() – JSON-RPC endpoints without UI components
  • ServiceSet::none() – No background work, suitable for library embedding

DomainSet – Domain Family Activation

DomainSet controls which high-level feature families are present at runtime. The implementation at src/core/runtime/builder.rs at line 176 defines this as a selector for functional domains such as agents, memory, threads, and web3 capabilities.

Available options include:

  • DomainSet::full() – Activates all domain families
  • DomainSet::harness() – Minimal set for library use (agents, memory, threads only)
  • DomainSet::none() – Kernel-only mode with no high-level domains

ToolGroups – Tool Visibility Control

The tool_groups field exposed via CoreBuilder::tool_groups determines how agent tools are advertised and accessible:

  • ToolGroups::packed() – Default tool packing with all tools available
  • ToolGroups::advertised() – Tools visible but with restricted access patterns
  • ToolGroups::none() – Tools completely removed from the runtime

Building a Runtime with CoreBuilder

The fluent API chains configuration methods before materializing the runtime. The builder stores selections as struct fields (services: ServiceSet, domains: DomainSet) and validates them during build().

let runtime = CoreBuilder::new(HostKind::Cli)
    .domains(DomainSet::full())
    .services(ServiceSet::desktop())
    .tool_groups(ToolGroups::packed())
    .build()?;

During the build() execution, the CoreBuilder performs three distinct phases:

  1. Registers controllers for each enabled domain using the DomainSet flags
  2. Spawns selected background services according to the ServiceSet configuration
  3. Initializes the tool registry with the chosen ToolGroups visibility settings

Configuration Examples

The repository provides concrete implementations demonstrating extreme ends of the configuration spectrum.

Headless Library Usage

For testing or embedding scenarios requiring minimal footprint, the examples/embed_headless.rs file demonstrates a service-free configuration:

use openhuman_core::{CoreBuilder, DomainSet, HostKind, ServiceSet};

let runtime = CoreBuilder::new(HostKind::Cli)
    .domains(DomainSet::harness())
    .services(ServiceSet::none())
    .tool_groups(ToolGroups::none())
    .build()?;

This pattern eliminates background services entirely while retaining core agent, memory, and thread capabilities.

Full Desktop Launch

The product UI configuration appears in examples/embed_kernel.rs, utilizing the complete service stack:

use openhuman_core::{CoreBuilder, DomainSet, HostKind, ServiceSet};

let runtime = CoreBuilder::new(HostKind::detect_standalone())
    .domains(DomainSet::full())
    .services(ServiceSet::desktop())
    .build()?;

This configuration enables the Tauri UI, socket servers, cron jobs, and all domain families.

Implementation Details

The CoreBuilder implementation resides in src/core/runtime/builder.rs, with public exports through src/core/runtime/mod.rs and the facade at src/lib.rs. The struct maintains independent fields for each axis, ensuring that disabling a domain does not automatically remove its associated background services, and vice versa.

Key implementation files include:

  • src/core/runtime/builder.rs – Contains the CoreBuilder struct, ServiceSet definition (lines 35-39), and DomainSet definition (line 176)
  • src/core/runtime/mod.rs – Re-exports the builder and related types for public use
  • src/lib.rs – Public façade that exposes CoreBuilder, CoreRuntime, DomainSet, ServiceSet, and TokenSource

Summary

  • CoreBuilder composes runtimes through three independent axes: ServiceSet, DomainSet, and ToolGroups
  • ServiceSet controls background infrastructure like sockets and cron jobs without affecting domain logic
  • DomainSet activates feature families (agents, memory, web3) independently of service configuration
  • ToolGroups manages tool visibility from fully packed to completely disabled
  • The build() method materializes a CoreRuntime after registering controllers, spawning services, and initializing tool registries
  • Examples in examples/embed_headless.rs and examples/embed_kernel.rs demonstrate minimal and maximal configurations

Frequently Asked Questions

What is the difference between ServiceSet and DomainSet?

ServiceSet configures background infrastructure processes such as transport listeners and periodic jobs, while DomainSet activates high-level functional capabilities like agents, memory management, and thread handling. These axes remain independent—disabling a domain does not automatically disable its background services, allowing flexible combinations like headless API servers with full domain capabilities.

How do I create a minimal runtime for testing?

Import CoreBuilder from openhuman_core and chain ServiceSet::none() with DomainSet::harness() to eliminate background services while preserving essential agent and memory functionality. The examples/embed_headless.rs file provides a complete reference implementation for this pattern.

Where is the CoreBuilder implementation located?

The primary implementation resides in src/core/runtime/builder.rs, with struct definitions for ServiceSet at lines 35-39 and DomainSet at line 176. Public exports appear in src/core/runtime/mod.rs and the library facade at src/lib.rs, making CoreBuilder, CoreRuntime, DomainSet, ServiceSet, and TokenSource available to embedders.

Can I mix different ServiceSet and DomainSet combinations?

Yes, the three axes are designed to be orthogonal. You can combine ServiceSet::headless_api() with DomainSet::full() for a JSON-RPC server with all features, or ServiceSet::desktop() with DomainSet::harness() for a UI-driven application with limited domain capabilities. The builder validates these combinations during the build() phase to ensure compatibility.

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 →