How ServiceSet, DomainSet, and ToolGroups Are Configured at Runtime in OpenHuman

OpenHuman configures runtime behavior through three orthogonal builder axes—ServiceSet for transport selection, DomainSet for domain family activation, and ToolGroups for tool visibility—each set via the CoreBuilder API before instantiation.

The OpenHuman core runtime uses a declarative builder pattern to assemble background services, domain controllers, and agent tool registries. Understanding how ServiceSet, DomainSet, and ToolGroups are configured at runtime allows developers to tailor the framework for desktop applications, headless APIs, or embedded harnesses without modifying core source code.

ServiceSet: Configuring Transports and Background Services

The ServiceSet struct, defined in src/core/runtime/builder.rs (lines 59‑65), controls which background services and transports are initialized when the core starts. Each field is a Boolean flag representing a specific capability such as HTTP servers, Socket.IO, cron schedulers, or channel listeners.

Available Presets

The builder provides preset constructors for common deployment scenarios:

  • ServiceSet::desktop() – Enables the full suite including HTTP server, WebSocket transports, and system tray integration.
  • ServiceSet::headless_api() – Configures only the HTTP transport layer suitable for cloud deployments.
  • ServiceSet::none() – Disables all transports for library-only usage.
  • ServiceSet::embedded() – Starts background processing loops without exposing RPC endpoints.
use openhuman_core::{CoreBuilder, ServiceSet};

// Configure for a headless server environment
let services = ServiceSet::headless_api();
let builder = CoreBuilder::default().with_services(services);

The flags are consumed during CoreBuilder::build(), where src/core/runtime/builder.rs wires the selected transports to the appropriate background loops.

DomainSet: Enabling Domain Families

DomainSet, located in src/core/runtime/builder.rs immediately following ServiceSet (lines 59‑70), determines which domain families are registered with the runtime. Each Boolean field corresponds to a DomainGroup variant defined in src/core/all.rs, controlling the availability of controllers, stores, and event subscribers.

DomainGroup Variants

The runtime recognizes distinct domain families including:

  • agent – Agent lifecycle management and state machines
  • memory – Vector stores and episodic memory systems
  • threads – Conversation thread management
  • config – Dynamic configuration stores
  • security – Authentication and authorization layers
  • flows – Workflow execution engines
  • skills – Skill registries and loaders
  • mcp – Model Context Protocol handlers
  • channels – Message bus implementations
  • web3 – Blockchain interaction layers
  • voice – Speech-to-text and text-to-speech services
  • media – Media processing pipelines

Preset Configurations

The framework provides three primary presets:

use openhuman_core::DomainSet;

// Enable every domain family (default desktop behavior)
let full = DomainSet::full();

// Minimal core for embedded agents: agent + memory + threads + config + security
let harness = DomainSet::harness();

// Disable all domain-specific controllers
let empty = DomainSet::none();

The chosen set is passed to CoreBuilder::with_domains(), which registers only the selected controllers with the dependency injection container.

ToolGroups: Controlling Tool Visibility

ToolGroups manage the runtime visibility of agent tool collections through src/openhuman/tools/toolpacks/groups.rs. Unlike ServiceSet and DomainSet, which use Boolean flags, ToolGroups employ a three-state enum (GroupMode) to control how tool schemas are exposed on the wire.

GroupMode States

Each tool group identified by GroupId operates in one of three modes:

  • Advertised – Tool schemas appear on the /schema endpoint and the tools are callable by agents.
  • Withheld – Schemas are hidden from discovery, but the tools remain callable internally (useful for private agent capabilities).
  • Off – The entire group is omitted; neither schemas nor execution endpoints are registered.

Runtime Registration

Configure tool visibility before building the core:

use openhuman_core::tools::toolpacks::{ToolGroups, GroupId, GroupMode};

// Start with all groups packed (available but not necessarily advertised)
let mut groups = ToolGroups::packed();

// Hide web3 tools entirely for this deployment
groups = groups.with(GroupId::Web3, GroupMode::Off);

// Withhold system tools from schema endpoints but keep them callable
groups = groups.with(GroupId::System, GroupMode::Withheld);

let builder = CoreBuilder::default().with_tool_groups(groups);

The ToolGroups configuration is stored in src/core/runtime/context.rs within the CoreContext structure, making the visibility settings available to the HTTP schema endpoint at runtime.

Complete Integration Example

Combine all three configuration axes to create a minimal embedded harness:

use openhuman_core::{
    CoreBuilder,
    ServiceSet,
    DomainSet,
    tools::toolpacks::{ToolGroups, GroupId, GroupMode},
};

let core = CoreBuilder::default()
    // No network transports for embedded library use
    .with_services(ServiceSet::none())
    // Only core agent domains required for headless operation
    .with_domains(DomainSet::harness())
    // Configure tool visibility: hide web3, advertise agent tools
    .with_tool_groups(
        ToolGroups::packed()
            .with(GroupId::Web3, GroupMode::Off)
            .with(GroupId::Agent, GroupMode::Advertised)
    )
    .build()
    .await
    .expect("failed to build core");

This configuration creates a lightweight runtime suitable for embedding in third-party applications, with all blockchain tooling removed and only the essential service layer active.

Summary

  • ServiceSet in src/core/runtime/builder.rs controls transport initialization via Boolean flags and presets like desktop() and headless_api().
  • DomainSet in the same file enables domain families (agent, memory, web3, etc.) through the DomainGroup registry in src/core/all.rs.
  • ToolGroups in src/openhuman/tools/toolpacks/groups.rs manages tool visibility using GroupMode states (Advertised, Withheld, Off) rather than simple Booleans.
  • All three configurations are applied through CoreBuilder methods (with_services, with_domains, with_tool_groups) and stored in src/core/runtime/context.rs for runtime access.
  • Presets allow rapid configuration for common scenarios while retaining granular control for specialized deployments.

Frequently Asked Questions

How do I disable all network transports in OpenHuman?

Pass ServiceSet::none() to the builder. This disables HTTP servers, WebSockets, and Socket.IO while keeping background processing loops available, as implemented in src/core/runtime/builder.rs lines 59‑65.

What is the difference between DomainSet::full() and DomainSet::harness()?

DomainSet::full() activates every domain family including web3, voice, and media processing, suitable for full desktop applications. DomainSet::harness() limits the runtime to only agent, memory, threads, config, and security domains, creating a minimal core for embedded usage as defined in the builder presets.

Can I hide tool schemas but still allow agents to call the tools?

Yes. Set the tool group to GroupMode::Withheld in src/openhuman/tools/toolpacks/groups.rs. This mode removes the schemas from the /schema endpoint while keeping the execution endpoints active, allowing internal agents to invoke the tools without exposing them to external discovery.

Where are the ServiceSet and DomainSet stored after the core is built?

Both configurations are stored in the CoreContext struct defined in src/core/runtime/context.rs. The runtime uses this context to check which services should be started and which domain controllers should receive events during the application lifecycle.

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 →