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

> Discover how OpenHuman CoreBuilder crafts a CoreRuntime by configuring ServiceSet, DomainSet, and ToolGroups, then building it with the build() method.

- Repository: [Tiny Humans/openhuman](https://github.com/tinyhumansai/openhuman)
- Tags: internals
- Published: 2026-08-28

---

**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`](https://github.com/tinyhumansai/openhuman/blob/main/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`](https://github.com/tinyhumansai/openhuman/blob/main/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`](https://github.com/tinyhumansai/openhuman/blob/main/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()`.

```rust
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`](https://github.com/tinyhumansai/openhuman/blob/main/examples/embed_headless.rs) file demonstrates a service-free configuration:

```rust
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`](https://github.com/tinyhumansai/openhuman/blob/main/examples/embed_kernel.rs), utilizing the complete service stack:

```rust
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`](https://github.com/tinyhumansai/openhuman/blob/main/src/core/runtime/builder.rs), with public exports through [`src/core/runtime/mod.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/core/runtime/mod.rs) and the facade at [`src/lib.rs`](https://github.com/tinyhumansai/openhuman/blob/main/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`](https://github.com/tinyhumansai/openhuman/blob/main/src/core/runtime/builder.rs)** – Contains the CoreBuilder struct, ServiceSet definition (lines 35-39), and DomainSet definition (line 176)
- **[`src/core/runtime/mod.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/core/runtime/mod.rs)** – Re-exports the builder and related types for public use
- **[`src/lib.rs`](https://github.com/tinyhumansai/openhuman/blob/main/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`](https://github.com/tinyhumansai/openhuman/blob/main/examples/embed_headless.rs) and [`examples/embed_kernel.rs`](https://github.com/tinyhumansai/openhuman/blob/main/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`](https://github.com/tinyhumansai/openhuman/blob/main/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`](https://github.com/tinyhumansai/openhuman/blob/main/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`](https://github.com/tinyhumansai/openhuman/blob/main/src/core/runtime/mod.rs) and the library facade at [`src/lib.rs`](https://github.com/tinyhumansai/openhuman/blob/main/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.