What Are the Roles of the Two Main Rust Crates in OpenHuman: Core vs Desktop Shell
The openhuman crate implements the headless AI engine and business logic, while openhuman-app provides the Tauri-based desktop shell that embeds the core and handles native UI interactions.
OpenHuman is architected as a modular Rust project where the assistant’s intelligence is strictly decoupled from its user interface. The repository splits functionality between a domain-driven core library and a platform-specific desktop wrapper, allowing the AI engine to run both as a standalone headless service and as an embedded component inside a native application.
openhuman_core: The Business Logic Engine
The openhuman crate—defined in the repository root [Cargo.toml](https://github.com/tinyhumansai/openhuman/blob/main/Cargo.toml)—implements the business-logic core of the assistant. This crate contains no UI code and focuses entirely on agent orchestration, memory management, Web3 integrations, voice processing, and document handling.
Key Responsibilities
- RPC Server: Exposes JSON-RPC and HTTP endpoints via [
src/openhuman/platform/socket/ws_loop.rs](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/platform/socket/ws_loop.rs) for external communication. - Domain Logic: Houses all AI agent logic including the
Harnessbuilder in [src/openhuman/agent/harness.rs](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/agent/harness.rs) that executes prompt-to-response pipelines. - Compile-Time Gating: Uses feature flags (e.g.,
voice,web3,documents) to shrink the dependency graph for different deployment targets.
Binary and Library Targets
The crate dual-targets both a binary and library:
- Binary:
src/main.rsdefines theopenhuman-coreentry point that callsrun_core_from_argsto start a headless server. - Library:
src/lib.rsexposes theopenhuman_corelibrary used by external embedders and the desktop shell.
openhuman_app: The Tauri Desktop Shell
The openhuman_app crate—declared in [app/src-tauri/Cargo.toml](https://github.com/tinyhumansai/openhuman/blob/main/app/src-tauri/Cargo.toml)—provides the native desktop UI using Tauri and React. It embeds the core crate in-process and manages platform-specific concerns like windowing, notifications, and deep-link registration.
Shell Architecture
- Tauri Bridge: [
app/src-tauri/src/lib.rs](https://github.com/tinyhumansai/openhuman/blob/main/app/src-tauri/src/lib.rs) initializes the Tauri runtime and starts the embedded core process viacore_process::CoreProcessHandle. - UI Launch: [
app/src-tauri/src/main.rs](https://github.com/tinyhumansai/openhuman/blob/main/app/src-tauri/src/main.rs) launches the React frontend and sets up the Tokio runtime that hosts the core. - Transport Layer: Communicates with the core over an internal HTTP endpoint at
http://127.0.0.1:<port>/rpc, exposing Tauri commands likecore_rpc_tokenandcore_rpc_url.
Feature Forwarding
The shell ensures byte-identical builds by forwarding the product feature set to the core dependency. In app/src-tauri/Cargo.toml, the openhuman_core dependency explicitly lists enabled features:
[dependencies]
openhuman_core = { path = "../..", default-features = false, features = ["voice", "web3", "documents"] }
This alignment is enforced by the CI script scripts/ci/check-feature-forwarding.mjs to prevent drift between the headless core and the shipped desktop application.
How the Crates Integrate
Standalone Headless Mode
Running cargo run --bin openhuman-core invokes the core binary for CLI usage or server deployment. This mode starts the JSON-RPC server without any UI dependencies, making it suitable for CI pipelines, server hosting, or programmatic integration.
In-Process Desktop Embedding
When the Tauri shell launches, it embeds the core library directly within its own process. The shell initializes the core's Tokio runtime, then proxies frontend requests through the internal HTTP transport to the core's RPC handlers.
Separation of Concerns
- The core owns pure business logic, data models, and RPC contracts. It has zero dependencies on UI frameworks or windowing APIs.
- The shell owns platform-specific plumbing (macOS notifications, Windows deep-links, hardware access) and merely forwards user interactions to the core for processing.
Practical Code Examples
Running the Core Standalone
Use the Harness builder from openhuman_core to execute AI turns without the desktop shell:
use openhuman_core::Harness;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let harness = Harness::builder()
.provider(openhuman_core::providers::Provider::openai_compatible(
"https://api.openai.com/v1",
std::env::var("OPENAI_API_KEY")?,
).model("gpt-4o"))
.workspace(openhuman_core::workspace::Workspace::Ephemeral)
.access(openhuman_core::access::Access::full())
.backend_url("https://backend.tinyhumans.ai")
.build()
.await?;
let response = harness.run("Summarize the latest OpenHuman release notes.").await?;
println!("{}", response.message);
Ok(())
}
Key files: src/lib.rs, src/openhuman/agent/harness.rs.
Embedding the Core in Tauri
The desktop shell initializes the core by passing command-line arguments through to run_core_from_args:
// In app/src-tauri/src/lib.rs
use openhuman_core::run_core_from_args;
pub fn run() {
let args = std::env::args().skip(1).collect::<Vec<_>>();
if let Err(err) = run_core_from_args(&args) {
eprintln!("Core error: {err}");
std::process::exit(1);
}
}
Key files: app/src-tauri/src/lib.rs, src/main.rs.
Frontend RPC Calls
The React frontend communicates with the embedded core via a TypeScript client that targets the internal RPC endpoint:
import { coreRpcClient } from '@/services/coreRpcClient';
async function askAssistant(prompt: string) {
const result = await coreRpcClient.turn({
prompt,
sessionId: undefined,
});
return result.message;
}
Key files: app/src/services/coreRpcClient.ts, src/openhuman/platform/socket/ws_loop.rs.
Summary
openhuman_core(Cargo.toml,src/lib.rs): Headless AI engine exposing business logic, RPC services, and theHarnessexecution pipeline as both a binary and library.openhuman_app(app/src-tauri/Cargo.toml): Tauri-based desktop shell that embeds the core in-process, manages native platform APIs, and bridges React UI events to the core's HTTP transport.- Integration: The shell forwards feature flags to ensure identical builds, while the core remains UI-agnostic and runnable standalone via
openhuman-core.
Frequently Asked Questions
Can I run the OpenHuman AI without the desktop application?
Yes. Build and run cargo run --bin openhuman-core to start the headless JSON-RPC server defined in src/main.rs. This mode exposes all AI capabilities without UI dependencies, suitable for server deployments or CLI scripting.
How does the desktop app communicate with the core?
The Tauri shell spawns the core in-process within the same Tokio runtime, then communicates over an internal HTTP server at http://127.0.0.1:<port>/rpc. Frontend TypeScript code invokes Tauri commands like core_rpc_token that proxy to this endpoint, as implemented in app/src-tauri/src/lib.rs.
Why are features explicitly forwarded from the shell to the core?
The openhuman_app crate declares openhuman_core as a dependency with explicit feature flags to ensure the shipped desktop binary includes exactly the same domains (voice, web3, documents) as the standalone core build. This prevents runtime mismatches and is validated by scripts/ci/check-feature-forwarding.mjs.
Which crate should I modify to add new AI capabilities?
Add domain logic to the openhuman crate (root Cargo.toml). New capabilities should be exposed through the Harness in src/openhuman/agent/harness.rs and gated behind feature flags in the core's Cargo.toml. The shell (openhuman_app) only requires updates if you need to expose new UI controls or native platform integrations.
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 →