Configuring DomainSet and ServiceSet for Custom OpenHuman Runtimes: A Complete Guide
Use CoreBuilder with ServiceSet to select transport layers and DomainSet to enable specific domain families, allowing you to tailor the tinyhumansai/openhuman runtime from full desktop applications to headless APIs or embedded libraries.
OpenHuman provides a flexible, two-axis configuration system that lets you customize exactly which services start and which business logic domains are active. By combining ServiceSet and DomainSet through the CoreBuilder API, you can construct runtimes ranging from feature-rich desktop shells to minimal headless workers or pure library embedders.
Understanding the Two-Axis Configuration Model
OpenHuman’s runtime is configured along two independent axes that control orthogonal aspects of the system.
ServiceSet: Transport and Background Services
The ServiceSet axis determines which transport protocols and background services initialize at runtime. This controls how your runtime communicates with the outside world and manages internal scheduling.
Available presets include:
ServiceSet::desktop()– Activates all transports and services, including the full HTTP RPC server, Socket.IO, cron schedulers, and channel listeners. This is the configuration used by the desktop Tauri shell.ServiceSet::headless_api()– Starts only the HTTP JSON-RPC server, ideal for cloud deployments and server environments that need API access without UI components.ServiceSet::none()– Disables all transports, creating a pure library mode with no external network services.ServiceSet::embedded()– Configures a long-lived embedder that runs background work and internal processing but exposes no external transport layer.
Pass your chosen preset to CoreBuilder::services(..) when constructing the runtime.
DomainSet: Domain Families and Controllers
The DomainSet axis selects which domain families (controllers, tools, stores, and subscribers) are live at runtime. Each flag corresponds to a DomainGroup that represents a functional area of the system.
Domain families include: agent, memory, threads, config, security, flows, skills, mcp, channels, web3, voice, and media.
Available presets include:
DomainSet::full()– Enables every domain family, matching the default behavior of the desktop application.DomainSet::harness()– Activates only core kernel families required for an embeddable agent harness (agent,memory,threads,config, andsecurity).DomainSet::none()– Disables every domain family, leaving only always-on core infrastructure.
Provide the set to CoreBuilder::domains(..) to tailor the feature surface. You can also construct custom sets manually by setting individual boolean flags.
CoreBuilder API and Configuration Methods
The runtime composition happens through CoreBuilder, defined in src/core/runtime/builder.rs. This builder exposes methods to independently set both axes before calling build().await to instantiate the core.
According to the source code in src/embed/harness/builder.rs, the high-level facade exposes these methods for embedders:
use openhuman_core::{
CoreBuilder, DomainSet, ServiceSet,
};
let core = CoreBuilder::new()
// Enable only HTTP JSON-RPC and the cron scheduler
.services(ServiceSet::headless_api())
// Run only the kernel families required for an embedded agent
.domains(DomainSet::harness())
.build()
.await?;
The chosen sets are stored in the runtime context (src/core/runtime/context.rs), making them available throughout the application lifecycle.
Practical Configuration Examples
Full Desktop Runtime
Use this configuration when building a complete desktop application with all features enabled:
let core = CoreBuilder::new()
.services(ServiceSet::desktop()) // All transports + services
.domains(DomainSet::full()) // Every domain family enabled
.build()
.await?;
Headless Cloud Worker
Deploy a lightweight server that exposes only HTTP JSON-RPC while maintaining full business logic capabilities:
let core = CoreBuilder::new()
.services(ServiceSet::headless_api())
.domains(DomainSet::full()) // Keep all domain families
.build()
.await?;
Pure Library and Harness Mode
Create a minimal embeddable runtime with no network exposure and only essential kernel domains:
let core = CoreBuilder::new()
.services(ServiceSet::none())
.domains(DomainSet::harness())
.build()
.await?;
Custom Domain Selection
Selectively disable specific domains like voice and web3 while keeping other features:
let custom_domains = DomainSet {
agent: true,
memory: true,
threads: true,
config: true,
security: true,
flows: true,
skills: true,
mcp: true,
channels: true,
web3: false, // Disabled
voice: false, // Disabled
media: false,
};
let core = CoreBuilder::new()
.services(ServiceSet::desktop())
.domains(custom_domains)
.build()
.await?;
Embedded Host with Background Work
Run background tasks and internal processing without exposing external RPC endpoints:
let core = CoreBuilder::new()
.services(ServiceSet::embedded())
.domains(DomainSet::harness())
.build()
.await?;
Key Source Files and Implementation Details
Understanding where these configurations are defined helps when extending or debugging the runtime:
src/core/runtime/builder.rs– Contains the struct definitions forServiceSetandDomainSet, including their preset methods and documentation (lines 32-100).src/embed/harness/builder.rs– Exposes the high-levelCoreBuilderAPI used by embedders and application runners (lines 4-34).src/tui/runner.rs– Demonstrates constructing a core withDomainSet::full()andServiceSet::none()for the terminal UI runner (lines 122-127).src/core/runtime/context.rs– Holds the runtime context that carries the chosenDomainSetandServiceSetthroughout execution.src/lib.rs– Re-exportsCoreBuilder,DomainSet,ServiceSet, and related types for library consumers.
Summary
- ServiceSet controls transport layers (HTTP RPC, Socket.IO) and background services, with presets for desktop, headless API, embedded, and disabled modes.
- DomainSet controls which business logic families are active, with presets for full features, minimal harness, or completely disabled.
CoreBuildercomposes these axes independently viaservices()anddomains()methods beforebuild().await.- Configuration definitions live in
src/core/runtime/builder.rs, while practical examples appear insrc/tui/runner.rsand the harness builder. - You can construct manual
DomainSetinstances with individual boolean flags to create precisely tailored runtimes.
Frequently Asked Questions
What is the difference between ServiceSet and DomainSet in OpenHuman?
ServiceSet controls infrastructure concerns—transports like HTTP JSON-RPC, Socket.IO, and background schedulers—while DomainSet controls application logic by enabling or disabling specific domain families like agent, memory, or web3. They are independent axes, meaning you can run a headless HTTP API with only harness domains, or a desktop app with no transport (as shown in src/tui/runner.rs).
How do I create a headless OpenHuman server?
Pass ServiceSet::headless_api() to CoreBuilder::services() to start only the HTTP JSON-RPC server without Socket.IO or other desktop-specific services. You typically pair this with DomainSet::full() to keep all business logic available via the API, or use DomainSet::harness() for a minimal agent server.
Can I enable specific domains while disabling others in OpenHuman?
Yes. Instead of using presets like DomainSet::full(), instantiate DomainSet directly with struct literal syntax, setting boolean flags for each domain family (agent, memory, threads, config, security, flows, skills, mcp, channels, web3, voice, media). Pass this custom instance to CoreBuilder::domains().
Where are ServiceSet and DomainSet defined in the OpenHuman source code?
Both structs are defined in src/core/runtime/builder.rs (lines 32-100) according to the tinyhumansai/openhuman repository. The CoreBuilder API that consumes these types is exposed through src/embed/harness/builder.rs, and the runtime context holding these values is managed in src/core/runtime/context.rs.
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 →