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 listenersServiceSet::headless_api()– JSON-RPC endpoints without UI componentsServiceSet::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 familiesDomainSet::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 availableToolGroups::advertised()– Tools visible but with restricted access patternsToolGroups::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:
- Registers controllers for each enabled domain using the DomainSet flags
- Spawns selected background services according to the ServiceSet configuration
- 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 usesrc/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.rsandexamples/embed_kernel.rsdemonstrate 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →