What Is the DomainGroup Enum in OpenHuman? Runtime Domain Control Explained

The DomainGroup enum is the central runtime switch that determines which feature families (domains) are active in an OpenHuman process, controlling controller registration, tool visibility, and store initialization.

The DomainGroup enum serves as the backbone of OpenHuman's modular architecture in the tinyhumansai/openhuman repository, allowing the system to ship lean binaries while supporting extensive optional capabilities. Defined in the core runtime, this enum determines which controllers, agent tools, and persistence stores are compiled into and activated within a running instance according to the source code in src/core/all.rs.

DomainGroup Enum Definition and Structure

In src/core/all.rs, the DomainGroup enum (around line 91) defines the complete set of logical feature families available in the OpenHuman ecosystem. Each variant represents a distinct domain that owns specific controllers, stores, and runtime behaviors.

Core Variants and Architecture

The enum definition includes variants for major system capabilities:

pub enum DomainGroup {
    Agent,
    Memory,
    Threads,
    Config,
    Security,
    Automation,
    Integrations,
    Platform,
    Medulla,
    Channels,
    Web3,
    Mcp,
    Flows,
    Skills,
    Media,
    Voice,
    Hosted,
    Desktop,
    Runtimes,
    Inference,
}

The DomainGroup::ALL constant and the domain_group_all_lists_every_variant test ensure that every variant is accounted for across registries. Adding a new family requires updating the enum, the DomainSet presets, and the registration code to maintain compile-time safety.

How DomainGroup Controls Runtime Behavior

The enum functions as a gatekeeper throughout the OpenHuman stack, determining which code paths execute during initialization and which remain dormant.

DomainSet and CoreBuilder Integration

At startup, CoreBuilder constructs a DomainSet containing the active DomainGroup variants. The builder presets in src/core/runtime/builder.rs define common configurations:

  • DomainSet::full(): Activates all available domains for a complete instance
  • DomainSet::harness(): Minimal set for testing environments
  • Custom iteration: Select specific domains via DomainSet::from_iter()

Only domains present in this set are registered; omitted domains become invisible to the RPC layer and are treated as "unknown-method" calls.

Controller Registration Gating

During core initialization in src/core/all.rs, the system checks domain membership before registering controllers:

if domains.allows(DomainGroup::Web3) {
    register_web3_controllers(&mut builder);
}

If Web3 is not included in the active DomainSet, the corresponding controllers are never registered, effectively stripping that functionality from the process rather than merely disabling it.

Tool Classification and Registry Filtering

The tool_group function in src/openhuman/tools/ops.rs maps agent tool names to their owning DomainGroup:

pub fn tool_group(name: &str) -> DomainGroup {
    // Maps tool prefixes to domain variants
    // e.g., "wallet_status" -> DomainGroup::Web3
}

When a domain is disabled, the tool registry automatically omits associated tools, preventing agents from accessing unavailable functionality.

Practical Implementation Examples

Checking Domain Availability

Determine whether specific functionality is active before executing domain-dependent logic:

use openhuman_core::core::all::{DomainGroup, DomainSet};

fn is_web3_enabled(domains: &DomainSet) -> bool {
    domains.allows(DomainGroup::Web3)
}

Building a Minimal Core Configuration

Construct a lightweight OpenHuman instance with only essential domains:

use openhuman_core::core::{
    builder::CoreBuilder,
    runtime::{DomainSet, ServiceSet},
    all::DomainGroup,
};

let core = CoreBuilder::new()
    .domains(DomainSet::from_iter([
        DomainGroup::Agent,
        DomainGroup::Memory
    ]))
    .services(ServiceSet::none())
    .build()
    .await?;

This configuration registers only the Agent and Memory domains, excluding Web3, Voice, Media, and other optional capabilities to reduce resource consumption and attack surface.

Mapping Tools to Domain Groups

Automatically classify tools based on naming conventions:

use openhuman_core::openhuman::tools::ops::tool_group;
use openhuman_core::core::all::DomainGroup;

let tool_name = "wallet_status";
let domain = tool_group(tool_name);
assert_eq!(domain, DomainGroup::Web3);

DomainGroup Impact on System Architecture

Beyond simple feature toggles, the enum enforces architectural boundaries that affect persistence and security.

Store Ownership and Persistence

In src/core/runtime/context.rs, each persistent store is linked to a specific DomainGroup. When a domain is disabled, its associated stores are never initialized on disk, preventing data corruption from partial configurations and ensuring clean separation between domain-specific data.

Modular Security and Binary Size

The DomainGroup system enables compile-time and runtime pruning of unused capabilities. By excluding domains from the DomainSet, operators can reduce binary size by omitting unused controller code paths and minimize attack surface by disabling unnecessary RPC namespaces.

Summary

  • The DomainGroup enum in src/core/all.rs defines all available feature families in OpenHuman, including Agent, Memory, Web3, Voice, and Flows.
  • DomainSet configurations determine which domains are active at runtime, with CoreBuilder handling the initialization logic in src/core/runtime/builder.rs.
  • Controllers are conditionally registered based on domains.allows(DomainGroup::Variant) checks in src/core/all.rs, completely excluding disabled functionality from the RPC layer.
  • The tool_group function in src/openhuman/tools/ops.rs automatically classifies agent tools by domain, hiding tools when their associated domain is inactive.
  • Store initialization in src/core/runtime/context.rs respects domain boundaries, ensuring disabled domains never create persistent storage.
  • This architecture supports modular deployment, allowing operators to ship minimal binaries while maintaining the option to enable advanced capabilities through configuration changes.

Frequently Asked Questions

What happens if I call a tool from a disabled DomainGroup?

The tool registry automatically filters out tools belonging to inactive domains. If an agent attempts to invoke such a tool, the system returns an "unknown-method" error, identical to calling a non-existent function. This prevents accidental execution of disabled capabilities while maintaining consistent error handling across the RPC layer.

How do I add a custom domain to OpenHuman?

Adding a new domain requires three steps: First, add a new variant to the DomainGroup enum in src/core/all.rs. Second, update the domain_group_all_lists_every_variant test to include your new variant. Finally, wrap your controller registration logic with if domains.allows(DomainGroup::YourVariant) checks to conditionally load the domain based on the active DomainSet.

Can I change DomainGroup settings after the core starts?

No, DomainGroup membership is determined at initialization time through CoreBuilder and remains immutable for the process lifetime. The DomainSet is fixed after CoreBuilder::build() completes to ensure consistent runtime behavior. To change active domains, you must restart the process with a different DomainSet configuration.

Where does OpenHuman define which tools belong to which DomainGroup?

The mapping logic resides in src/openhuman/tools/ops.rs within the tool_group function. This helper analyzes tool names and returns the appropriate DomainGroup variant. For example, tools prefixed with "wallet_" or "blockchain_" return DomainGroup::Web3, while audio processing tools map to DomainGroup::Voice, as implemented in the tinyhumansai/openhuman source code.

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 →