mirror of
https://github.com/tinyhumansai/openhuman.git
synced 2026-07-27 21:08:00 +00:00
719 lines
40 KiB
TOML
719 lines
40 KiB
TOML
[package]
|
|
name = "openhuman"
|
|
version = "0.63.5"
|
|
edition = "2021"
|
|
description = "OpenHuman core business logic and RPC server"
|
|
autobins = false
|
|
# build.rs globs tests/raw_coverage/*.rs into the single `raw_coverage_all`
|
|
# integration target (see tests/raw_coverage_all.rs). Those files used to be ~76
|
|
# individual `tests/*.rs` targets, each statically relinking the whole crate —
|
|
# collapsing them into one target removes ~75 full-crate link steps per test run.
|
|
build = "build.rs"
|
|
|
|
[[bin]]
|
|
name = "openhuman-core"
|
|
path = "src/main.rs"
|
|
|
|
[[bin]]
|
|
name = "slack-backfill"
|
|
path = "src/bin/slack_backfill.rs"
|
|
|
|
[[bin]]
|
|
name = "gmail-backfill-3d"
|
|
path = "src/bin/gmail_backfill_3d.rs"
|
|
|
|
[[bin]]
|
|
name = "memory-tree-init-smoke"
|
|
path = "src/bin/memory_tree_init_smoke.rs"
|
|
|
|
[[bin]]
|
|
name = "inference-probe"
|
|
path = "src/bin/inference_probe.rs"
|
|
|
|
[[bin]]
|
|
name = "harness-subagent-audit"
|
|
path = "src/bin/harness_subagent_audit.rs"
|
|
|
|
[[bin]]
|
|
name = "test-mcp-stub"
|
|
path = "src/bin/test_mcp_stub.rs"
|
|
|
|
[[bin]]
|
|
name = "openhuman-fleet"
|
|
path = "src/bin/fleet.rs"
|
|
# The fleet supervisor embeds the axum control-plane server, so it only builds
|
|
# with the HTTP transport compiled in (#5048). Under `--no-default-features`
|
|
# (no `http-server`) this target is skipped rather than failing to link.
|
|
required-features = ["http-server"]
|
|
|
|
# Embedded-RSS benchmark harness (#5046). Gated behind the default-OFF
|
|
# `rss-bench` feature so no benchmark code enters the shipped build. Build with
|
|
# `cargo build --release --features rss-bench --bin rss-bench`.
|
|
[[bin]]
|
|
name = "rss-bench"
|
|
path = "src/bin/rss_bench.rs"
|
|
required-features = ["rss-bench"]
|
|
|
|
# Stateful library profiling workloads (memory ingestion + real sub-agent
|
|
# delegation under a hermetic mock provider). Local/dev only.
|
|
[[bin]]
|
|
name = "library-profile"
|
|
path = "src/bin/library_profile/main.rs"
|
|
required-features = ["rss-bench"]
|
|
|
|
[lib]
|
|
name = "openhuman_core"
|
|
crate-type = ["rlib"]
|
|
|
|
[dependencies]
|
|
# tiny.place A2A social network SDK — published on crates.io and patched below
|
|
# to the vendored tiny.place submodule so OpenHuman can test SDK changes before
|
|
# publishing.
|
|
tinyplace = "2.0"
|
|
# tinyflows — host-agnostic workflow engine (typed node graph → validate → compile →
|
|
# run on tinyagents). Powers the "Workflows" feature via the seam in
|
|
# `src/openhuman/tinyflows/` + the `flows::` domain. Pulls tinyagents 2.1 transitively
|
|
# (same version OpenHuman uses directly, preserving one trait identity). Published
|
|
# on crates.io and patched below to the vendored submodule.
|
|
#
|
|
# `mock` feature: enables `tinyflows::caps::mock::mock_capabilities()` — the
|
|
# deterministic in-memory capability bundle the flows `dry_run_workflow` agent
|
|
# tool (Phase 5b) runs a *draft* graph against so the workflow-builder agent can
|
|
# self-verify a proposal without any real side effects (no real LLM/tool/HTTP/code).
|
|
#
|
|
# Optional: exclusive to the default-ON `flows` feature (#4797). A slim build
|
|
# without `flows` drops this crate and its `jaq-*` JSON-query stack entirely.
|
|
tinyflows = { version = "0.5", features = ["mock"], optional = true }
|
|
# TinyJuice — host-agnostic TokenJuice compression engine. OpenHuman keeps
|
|
# config/RPC/tool/runtime adapters in `src/openhuman/tokenjuice/` and patches
|
|
# this dependency to the vendored submodule below.
|
|
tinyjuice = { version = "0.2.1", default-features = false }
|
|
# TinyAgents — Rust LLM orchestration framework (LangGraph/LangChain-style):
|
|
# durable state graphs, agent-loop harness, model/tool registries, REPL +
|
|
# `.rag` workflow language. openhuman's agent engine + orchestration run on this
|
|
# crate's primitives via the adapter seam in `src/openhuman/tinyagents/` (issue
|
|
# #4249): every turn drives through the harness; the workflow phase DAG, team
|
|
# member runtime, parallel fan-out, and multi-stage delegation run on graphs.
|
|
# We wire openhuman's own Provider/Tool, not the removed bundled openai client.
|
|
# The `sqlite` feature is enabled now that openhuman's direct rusqlite pin is
|
|
# aligned to 0.40, avoiding duplicate `links = "sqlite3"` native bindings.
|
|
# Durable graph checkpoints still use `SqlRunLedgerCheckpointer` until the
|
|
# migration re-points those rows to the crate checkpointer.
|
|
# The `repl` feature (embedded Rhai `.ragsh` session runtime powering the
|
|
# `rhai_workflows` language-workflow tool, `src/openhuman/rhai_workflows/`) is
|
|
# NOT enabled here — the default-ON `flows` feature turns it on via
|
|
# `tinyagents/repl` (#4797), so a slim build without `flows` sheds `rhai`.
|
|
# The crate itself can never be dropped: 26+ domains consume tinyagents.
|
|
tinyagents = { version = "2.1", features = ["sqlite"] }
|
|
# TinyCortex — Rust core for the memory engine (store/chunks/tree/retrieval/
|
|
# queue/ingest/score + long tail), vendored as a git submodule and patched
|
|
# below to `vendor/tinycortex`. OpenHuman's memory subsystem migrates onto this
|
|
# crate through the adapter seam in `src/openhuman/tinycortex/` (mirroring the
|
|
# tinyagents seam): engine logic (including provider sync pipelines) in the
|
|
# crate; RPC, agent tools, sync scheduling/credentials/events, security gating,
|
|
# and the global singleton stay host-side. rusqlite/git2 are
|
|
# aligned to the host pins (=0.40 / 0.21) so one bundled SQLite + one libgit2
|
|
# link. The submodule intentionally tracks reviewed upstream main commits;
|
|
# keep this semver requirement compatible with the vendored crate version.
|
|
tinycortex = { version = "0.1", features = ["git-diff", "persona", "sync"] }
|
|
tinychannels = { version = "0.1", features = ["relay-websocket"] }
|
|
serde = { version = "1", features = ["derive"] }
|
|
serde_json = "1"
|
|
serde_repr = "0.1"
|
|
serde_yaml = "0.9"
|
|
# dhat — heap profiler for the offline `library-profile` benchmark binary only.
|
|
# Default-OFF, dev-only: pulled in solely by the `rss-bench-dhat` feature so it
|
|
# never enters the shipped desktop/library build (same posture as `rss-bench`).
|
|
dhat = { version = "0.3", optional = true }
|
|
# (Removed `html2md` dep. dhat-rs profiling on real Gmail inboxes
|
|
# showed `html2md::walk` and `html2md::tables::handle` allocating
|
|
# ~894 MB peak heap on a 10 KB HTML input from Otter.ai-style emails
|
|
# (deeply-nested table-as-layout HTML). Cause: recursive walker holding
|
|
# per-frame Vec state across nesting layers + 5 sequential
|
|
# `regex::replace_all` passes in `clean_markdown` each producing a
|
|
# fresh full-size String. We now use a linear-time tag-and-entity
|
|
# stripper (`fast_html_to_text` in
|
|
# providers/gmail/post_process.rs) and prefer the email's
|
|
# `text/plain` MIME part when available.)
|
|
# TLS: rustls only in the base declaration, so Linux/macOS — including the
|
|
# headless embedding target (#5046) — link a single TLS stack + cert set
|
|
# (Mozilla webpki-roots). Windows re-adds `native-tls` via the
|
|
# `[target.'cfg(windows)'.dependencies]` block below (Cargo unions features
|
|
# per target), because `src/openhuman/tls/mod.rs` deliberately routes the
|
|
# Windows client through the SChannel/OS cert store for corporate MITM +
|
|
# AV root CAs. So the two TLS backends coexist only on Windows, never on
|
|
# the RAM-sensitive platforms.
|
|
reqwest = { version = "0.12", default-features = false, features = ["json", "blocking", "rustls-tls", "stream", "http2", "multipart", "socks"] }
|
|
# Already in-tree via reqwest/hyper; named directly so `IntegrationClient::get_bytes`
|
|
# can return `bytes::Bytes` without a copy.
|
|
bytes = "1"
|
|
tokio = { version = "1", features = ["full", "sync"] }
|
|
once_cell = "1.19"
|
|
parking_lot = "0.12"
|
|
log = "0.4"
|
|
libc = "0.2"
|
|
nu-ansi-term = "0.46"
|
|
env_logger = "0.11"
|
|
base64 = "0.22"
|
|
aes-gcm = "0.10"
|
|
argon2 = "0.5"
|
|
rand = "0.10"
|
|
dirs = "5"
|
|
sha2 = "0.10"
|
|
# Line-level text diffs for the memory_diff module (modified-item unified diffs).
|
|
similar = "2"
|
|
# Git-backed change ledger for the memory_diff module: snapshots are commits,
|
|
# checkpoints are tags, read markers are refs, diffs are git tree diffs.
|
|
# Vendored libgit2 (no system git dependency on end-user machines).
|
|
git2 = { version = "0.21", default-features = false, features = ["vendored-libgit2"] }
|
|
# Legacy SHA-1 only used for Tencent COS HMAC-SHA1 signing (yuanbao
|
|
# channel media upload). Not used for any new security-sensitive work.
|
|
sha1 = "0.10"
|
|
hmac = "0.12"
|
|
# Archive extraction for the Node.js runtime bootstrap. Unix Node
|
|
# distributions ship as .tar.xz, Windows as .zip. `xz2` with `static`
|
|
# bundles liblzma so we don't need it as a system dependency.
|
|
tar = "0.4"
|
|
xz2 = { version = "0.1", features = ["static"] }
|
|
zip = { version = "2", default-features = false, features = ["deflate"] }
|
|
# gzip decoder for the Piper tar.gz binary releases on macOS / Linux. Already
|
|
# pulled in transitively by zip's `deflate` feature; declared directly so
|
|
# the installer module can `use flate2::read::GzDecoder`.
|
|
flate2 = "1"
|
|
# Real timeout for `node --version` probes in the runtime resolver. Guards
|
|
# against a broken shim on PATH hanging the bootstrap forever.
|
|
wait-timeout = "0.2"
|
|
uuid = { version = "1", features = ["v4"] }
|
|
anyhow = "1.0"
|
|
async-trait = "0.1"
|
|
chacha20poly1305 = "0.10"
|
|
# Wipe master keys / decrypted secret buffers from memory on drop (audit C9).
|
|
# Already present transitively (resolved to 1.8.x via the *-dalek / cipher
|
|
# crates); declared directly so the keyring module can `use zeroize::Zeroizing`.
|
|
zeroize = "1"
|
|
x25519-dalek = { version = "2", features = ["static_secrets"] }
|
|
hkdf = "0.12"
|
|
hex = "0.4"
|
|
tokio-util = { version = "0.7", features = ["rt", "io"] }
|
|
# tokio-tungstenite is declared per-target below so the TLS backend
|
|
# (native-tls on Windows, rustls on macOS / Linux) matches the reqwest
|
|
# backend selected at each TLS call site.
|
|
futures = "0.3"
|
|
rusqlite = { version = "=0.40.0", features = ["bundled"] }
|
|
chrono = { version = "0.4", features = ["serde"] }
|
|
iana-time-zone = "0.1"
|
|
cron = "0.12"
|
|
futures-util = "0.3"
|
|
directories = "6"
|
|
toml = "1.0"
|
|
schemars = "1.2"
|
|
tracing = { version = "0.1", default-features = false }
|
|
tracing-log = "0.2"
|
|
tracing-subscriber = { version = "0.3", default-features = false, features = ["fmt", "ansi", "env-filter"] }
|
|
tracing-appender = "0.2"
|
|
urlencoding = "2.1"
|
|
motosan-ai-oauth = { version = "0.2", features = ["codex"] }
|
|
thiserror = "2.0"
|
|
ring = "0.17"
|
|
chrono-tz = "0.10"
|
|
dotenvy = "0.15"
|
|
console = "0.16"
|
|
regex = "1.10"
|
|
# Multi-pattern fixed-string DFA matcher used by `routing::quality` for
|
|
# refusal/empty-noise detection on local-model responses. Already in the
|
|
# dep graph transitively via `regex` (which uses it for literal
|
|
# optimization); declared directly here so `openhuman` owns the
|
|
# version pin and the import isn't an unstable transitive surface.
|
|
aho-corasick = "1.1"
|
|
walkdir = "2"
|
|
glob = "0.3"
|
|
hostname = "0.4.2"
|
|
rustls = { version = "0.23", features = ["ring"] }
|
|
rustls-pki-types = "1.14.0"
|
|
tokio-rustls = "0.26.4"
|
|
webpki-roots = "1.0.6"
|
|
sysinfo = { version = "0.33", default-features = false, features = ["system"] }
|
|
keyring = { version = "3", features = ["apple-native", "windows-native", "linux-native"] }
|
|
clap = { version = "4.5", features = ["derive"] }
|
|
lettre = { version = "0.11.22", default-features = false, features = ["builder", "smtp-transport", "rustls-tls"], optional = true }
|
|
# HTTP + Socket.IO server transport — the `/rpc` JSON-RPC endpoint, `/v1`
|
|
# OpenAI-compat router, agentbox/http_host sub-servers, and the Socket.IO
|
|
# live-event bridge. Exclusive to the default-ON `http-server` feature (#5048):
|
|
# a slim/embedded build without it (`--no-default-features`) sheds `axum` +
|
|
# `socketioxide` and never binds a listener — the core still runs background
|
|
# services and answers over the CLI/native dispatch surface. See the
|
|
# `http-server` feature note below and `src/core/http_server_status.rs`.
|
|
axum = { version = "0.8", default-features = false, features = ["http1", "json", "tokio", "query", "ws", "macros"], optional = true }
|
|
sentry = { version = "0.47.0", default-features = false, optional = true, features = ["backtrace", "contexts", "panic", "tracing", "debug-images", "reqwest", "rustls"] }
|
|
tokio-stream = { version = "0.1.18", features = ["full"] }
|
|
url = "2"
|
|
socketioxide = { version = "0.15", features = ["extensions"], optional = true }
|
|
whisper-rs = { version = "0.16", optional = true }
|
|
image = { version = "0.25", default-features = false, features = ["png", "jpeg"] }
|
|
tempfile = "3"
|
|
cpal = { version = "0.15", optional = true }
|
|
hound = { version = "3.5", optional = true }
|
|
enigo = "0.3"
|
|
arboard = "3"
|
|
rdev = "0.5"
|
|
fs2 = "0.4"
|
|
# Cross-platform battery probe for the scheduler gate. Maintained fork of
|
|
# the abandoned `battery` crate; same `use battery::*;` API surface. Used
|
|
# only by `openhuman::scheduler_gate::signals` to decide when to throttle
|
|
# background LLM work on laptops.
|
|
starship-battery = "0.10"
|
|
ethers-core = { version = "2.0.14", default-features = false }
|
|
ethers-signers = { version = "2.0.14", default-features = false }
|
|
# Multi-chain wallet signing.
|
|
# - bitcoin: P2WPKH PSBT build/sign/broadcast (includes secp256k1).
|
|
# - ed25519-dalek: Solana transaction signing.
|
|
# - bs58: Solana base58 addresses + Tron base58check addresses.
|
|
bitcoin = { version = "0.32", default-features = false, features = ["std", "secp-recovery", "rand-std"], optional = true }
|
|
ed25519-dalek = { version = "2", default-features = false, features = ["std", "rand_core"] }
|
|
bs58 = { version = "0.5", default-features = false, features = ["std", "check"] }
|
|
# Shared BIP-39 mnemonic → seed for non-EVM chains (BTC P2WPKH derivation,
|
|
# Tron secp256k1 derivation, Solana ed25519 SLIP-0010 derivation). Same crate
|
|
# ethers-signers uses internally, exposed as a direct dep so we can derive
|
|
# off the recovery phrase without going through the EVM signer wrapper.
|
|
coins-bip39 = "0.8"
|
|
# Solana off-curve check for ATA derivation (find_program_address).
|
|
curve25519-dalek = { version = "4", default-features = false, features = ["alloc"], optional = true }
|
|
|
|
fantoccini = { version = "0.22.0", optional = true, default-features = false, features = ["rustls-tls"] }
|
|
pdf-extract = { version = "0.10", optional = true }
|
|
# The WhatsApp Web provider (and its `whatsapp-rust` / `wacore` / `serde-big-array`
|
|
# stack) now lives in the tinychannels crate; the `whatsapp-web` feature forwards
|
|
# to `tinychannels/whatsapp-web`.
|
|
ppt-rs = { version = "0.2.14", optional = true }
|
|
# Terminal chat UI (`openhuman tui` / `chat`). Exclusive to the default-ON
|
|
# `tui` feature (see `[features]` below): a slim / headless build without `tui`
|
|
# drops both `ratatui` and `crossterm`. Kept in lockstep — ratatui 0.30
|
|
# re-exports crossterm 0.29, so declaring crossterm directly at the same major
|
|
# unifies to a single crossterm in the dep graph. Only compiled into
|
|
# `src/openhuman/tui/` behind `#[cfg(feature = "tui")]`.
|
|
ratatui = { version = "0.30", optional = true }
|
|
crossterm = { version = "0.29", optional = true }
|
|
# Terminal column-width measurement for the `tui` chat renderer
|
|
# (`src/openhuman/tui/render.rs`); only compiled behind `#[cfg(feature = "tui")]`.
|
|
unicode-width = { version = "0.2", optional = true }
|
|
# Native-Rust `.docx` writer for the `generate_document` tool (GH #4847).
|
|
# Pure Rust (no subprocess / managed runtime), MIT-licensed, actively
|
|
# maintained (2.8M downloads, last release 0.4.20 — Apr 2026). Mirrors the
|
|
# `ppt-rs` presentation engine: synthesise bytes in-process, hand them to
|
|
# the byte-agnostic artifact pipeline. `default-features` keeps the crate's
|
|
# image support (unused here, but avoids a bespoke feature list drifting).
|
|
docx-rs = { version = "0.4.20", optional = true }
|
|
|
|
[target.'cfg(windows)'.dependencies]
|
|
# Windows: tokio-tungstenite uses native-tls (schannel) so wss://
|
|
# connections honor the Windows cert store, including corporate CAs
|
|
# installed by AV / TLS-inspection proxies. See run-dev-win.sh notes.
|
|
tokio-tungstenite = { version = "0.24", default-features = false, features = ["connect", "handshake", "native-tls"] }
|
|
# Windows re-adds reqwest's native-tls backend (dropped from the base decl in
|
|
# `[dependencies]`) so `tls::tls_client_builder()` can call `.use_native_tls()`
|
|
# and reach the SChannel/OS cert store — same rationale as tokio-tungstenite
|
|
# above. Cargo unions these features with the base rustls decl, so on Windows
|
|
# reqwest carries both backends; Linux/macOS keep rustls only.
|
|
reqwest = { version = "0.12", default-features = false, features = ["native-tls"] }
|
|
# AppContainer / process-jail backend in `openhuman::cwd_jail`.
|
|
# Feature list mirrors the Win32 surface used by cwd_jail/windows.rs:
|
|
# AppContainer profile APIs, ACL editing, STARTUPINFOEXW process spawn,
|
|
# and the GENERIC_* file access masks.
|
|
windows-sys = { version = "0.61", features = [
|
|
"Win32_Foundation",
|
|
"Win32_Security",
|
|
"Win32_Security_Authorization",
|
|
"Win32_Security_Isolation",
|
|
"Win32_Storage_FileSystem",
|
|
"Win32_System_Memory",
|
|
"Win32_System_Threading",
|
|
] }
|
|
|
|
[target.'cfg(not(windows))'.dependencies]
|
|
# macOS / Linux: keep rustls + Mozilla webpki-roots — the historical
|
|
# default. Avoids pulling OpenSSL as a runtime dep on Linux.
|
|
tokio-tungstenite = { version = "0.24", default-features = false, features = ["connect", "handshake", "rustls-tls-webpki-roots"] }
|
|
|
|
[target.'cfg(target_os = "macos")'.dependencies]
|
|
whisper-rs = { version = "0.16", features = ["metal"], optional = true }
|
|
# Contacts framework bindings for address book seeding.
|
|
objc2 = "0.6"
|
|
objc2-foundation = { version = "0.3", features = ["NSArray", "NSError", "NSObject", "NSString", "NSPredicate"] }
|
|
objc2-contacts = { version = "0.3.2", features = ["CNContact", "CNContactFetchRequest", "CNContactStore", "CNLabeledValue", "CNPhoneNumber"] }
|
|
block2 = "0.6"
|
|
|
|
[target.'cfg(target_os = "linux")'.dependencies]
|
|
landlock = { version = "0.4", optional = true }
|
|
rppal = { version = "0.22", optional = true }
|
|
|
|
[dev-dependencies]
|
|
# Enable sentry's TestTransport for runtime smoke of the observability
|
|
# before_send filter (see tests/observability_smoke.rs). `default-features
|
|
# = false` here is load-bearing — sentry's default feature set pulls in
|
|
# actix-web / actix-http / actix-server / sentry-actix and ~13 transitive
|
|
# crates we never use (and that bloat the dev Cargo.lock noticeably).
|
|
# TestTransport only needs the `test` feature.
|
|
sentry = { version = "0.47.0", default-features = false, features = ["test"] }
|
|
# axum is optional in `[dependencies]` (exclusive to the default-ON
|
|
# `http-server` feature, #5048), but ~17 `#[cfg(test)]` modules stand up
|
|
# in-process axum mock servers / call `build_core_http_router` regardless of
|
|
# the feature set under test. Declaring a plain (non-optional) dev-dep keeps
|
|
# those tests compiling in ALL test builds without per-file `#[cfg]` — mirrors
|
|
# the `sentry` dual-declaration above. The prod fns those tests exercise are
|
|
# still gated, so the *tests* naming them carry `#[cfg(feature = "http-server")]`.
|
|
axum = { version = "0.8", default-features = false, features = ["http1", "json", "tokio", "query", "ws", "macros"] }
|
|
# `tower` was a plain runtime dep only for its re-exports in the axum server
|
|
# path; with `http-server` optional it is test-only (tower::ServiceExt::oneshot
|
|
# drives the mock routers), so it lives here as a dev-dep now.
|
|
tower = { version = "0.5", default-features = false }
|
|
# Mock HTTP server for provider E2E tests (inference_provider_e2e).
|
|
wiremock = "0.6"
|
|
# Used in json_rpc_e2e to backdate mtime on stale lock files.
|
|
filetime = "0.2"
|
|
# `test-util` enables tokio's paused virtual clock (`start_paused`,
|
|
# `time::advance`) so the #4270 inference-heartbeat tests assert the periodic
|
|
# beat without real-time waits. Test-only — the runtime feature set in
|
|
# `[dependencies]` (`full`) intentionally excludes it.
|
|
tokio = { version = "1", features = ["test-util"] }
|
|
# Property-based testing for the adversarial-input surfaces (command classifier,
|
|
# encryption round-trip) — plan.md §6.3. Version already resolved in Cargo.lock.
|
|
proptest = "1"
|
|
|
|
[features]
|
|
default = ["tokenjuice-treesitter", "inference", "voice", "web3", "media", "documents", "meet", "skills", "flows", "mcp", "crash-reporting", "http-server", "channels", "tui", "medulla-local"]
|
|
# HTTP + Socket.IO server transport (#5048): the `/rpc` JSON-RPC endpoint and
|
|
# its auth middleware/CORS layer (`core::jsonrpc`, `core::auth`), the `/v1`
|
|
# OpenAI-compatible router (`inference::http`), the ad-hoc static-dir file
|
|
# server (`openhuman::http_host`), the AgentBox `/run` HTTP surface
|
|
# (`agentbox::http`), the WebSocket dictation stream
|
|
# (`inference::voice::streaming`), the `openhuman text-input run` dev server,
|
|
# the MCP Streamable-HTTP transport (`mcp_server::http`, additionally gated by
|
|
# `mcp`), and the Socket.IO live-event bridge (`core::socketio`). Default-ON —
|
|
# the desktop shell REQUIRES it (see the `HTTP_SERVER_COMPILED_IN` compile
|
|
# assert in `app/src-tauri/src/lib.rs`). Slim / headless-embedding builds opt
|
|
# out via `--no-default-features --features "<explicit list without
|
|
# http-server>"`, which drops the exclusive `axum` + `socketioxide` deps; the
|
|
# core then runs background services without binding a listener (`serve()`
|
|
# returns early) and is driven over the CLI / native dispatch surface instead.
|
|
#
|
|
# TYPE CARVE-OUT (see AGENTS.md): `core::socketio`'s inert event payload types
|
|
# (`WebChannelEvent`, `TurnUsagePayload`, `SubagentUsagePayload`,
|
|
# `SubagentProgressDetail`) stay compiled in BOTH builds — ~10 always-on
|
|
# domains construct them — so `pub mod socketio;` is UNGATED and only the
|
|
# socketioxide/axum-touching bodies are gated. Likewise `inference::http::types`
|
|
# and `EXTERNAL_OPENAI_COMPAT_PROVIDER` stay compiled for `core::auth`.
|
|
http-server = ["dep:axum", "dep:socketioxide"]
|
|
# AST-aware code compression (tree-sitter Rust/TS/Python grammars; C build).
|
|
# On by default; disable to fall back to the brace-depth heuristic.
|
|
tokenjuice-treesitter = [
|
|
"tinyjuice/tinyjuice-treesitter",
|
|
]
|
|
# In-process inference engine: the whisper.cpp STT engine
|
|
# (`inference::local::service::whisper_engine`) plus the `cpal` audio-device
|
|
# probe shared by voice capture and the accessibility microphone-permission
|
|
# check. Default-ON. Slim / headless builds opt out via
|
|
# `--no-default-features --features "<explicit list without inference>"`, which
|
|
# drops the exclusive `whisper-rs` (including the macOS `metal` variant and the
|
|
# `whisper-rs-sys` patch, which go inert once whisper-rs leaves the graph) and
|
|
# `cpal` dependencies. When off, the whisper facade resolves to
|
|
# `whisper_engine::stub` — in-process STT returns a disabled error, while the
|
|
# local-AI service still reaches Ollama / LM Studio over HTTP — and the
|
|
# microphone probe reports `Unknown`. `voice` requires this gate, so building
|
|
# `voice` always pulls `inference` in transitively.
|
|
inference = ["dep:whisper-rs", "dep:cpal"]
|
|
# Office-document tools: the `generate_presentation` (ppt-rs) and
|
|
# `generate_document` (docx-rs) agent tools, plus `pdf-extract` for PDF text
|
|
# extraction during multimodal file ingest. Default-ON. Slim / headless builds
|
|
# opt out via `--no-default-features --features "<explicit list without
|
|
# documents>"`, which drops all three crates. Leaf gate (no stub facade): when
|
|
# off, the two tools are absent from the tool list rather than degraded to an
|
|
# error, and PDF ingest degrades the file to a reference instead of extracted
|
|
# text (`agent::multimodal::extract_pdf_text`).
|
|
documents = ["dep:pdf-extract", "dep:ppt-rs", "dep:docx-rs"]
|
|
# Voice + audio_toolkit domains: STT/TTS providers, the standalone dictation
|
|
# server, always-on listening, and podcast audio generation/email delivery.
|
|
# Default-ON — the desktop app always ships with voice. Slim / headless builds
|
|
# opt out via `--no-default-features --features "<explicit list without voice>"`,
|
|
# which also drops the exclusive `hound` (WAV I/O) + `lettre` (podcast email)
|
|
# dependencies. Composes with the runtime `DomainSet::voice` flag (#4796): the
|
|
# feature narrows the compile-time surface, `DomainSet` gates it at runtime.
|
|
# Requires `inference` (the whisper engine + the cpal capture stack), so
|
|
# enabling `voice` turns `inference` on transitively.
|
|
voice = ["inference", "dep:hound", "dep:lettre"]
|
|
# Web3 domains: openhuman::wallet + openhuman::web3 + openhuman::x402 — the
|
|
# crypto wallet (multi-chain sign/broadcast), the high-level swap/bridge/dapp
|
|
# surface, and the x402 machine-payment protocol. Default-ON — the desktop app
|
|
# always ships with the wallet. Slim / headless builds opt out via
|
|
# `--no-default-features --features "<explicit list without web3>"`, which also
|
|
# drops the exclusive `bitcoin` (P2WPKH PSBT) + `curve25519-dalek` (Solana
|
|
# off-curve ATA) dependencies. Composes with the runtime `DomainSet::Web3` flag
|
|
# (#4796): the feature narrows the compile-time surface, `DomainSet` gates it at
|
|
# runtime. NOTE: this gate does NOT drop ethers-core / ethers-signers /
|
|
# coins-bip39 / bs58 / ed25519-dalek / ripemd — those are shared with the
|
|
# Polymarket tools + tinyplace on-chain payments + orchestration and stay
|
|
# always-on. When off, tinyplace payments + Polymarket writes degrade to
|
|
# graceful "wallet disabled" errors via the wallet/web3/x402 stub facades.
|
|
web3 = ["dep:bitcoin", "dep:curve25519-dalek"]
|
|
# Media-generation + image domains: the `media_generate_*` agent tools
|
|
# (image/video via GMI through the backend) and the `openhuman::image` tool
|
|
# contracts scaffold. Default-ON. Slim builds opt out via
|
|
# `--no-default-features --features "<explicit list without media>"`.
|
|
# Composes with the runtime `DomainSet::media` flag (#4796).
|
|
# NOTE: this gate sheds NO exclusive dependencies — media generation is
|
|
# backend-proxied (reqwest, shared) and the `image` crate is shared with
|
|
# channel media upload. It is a surface-only gate (drops the tool code +
|
|
# module from the compile), not a dependency-shedding one. There are no
|
|
# controllers / stores / subscribers tagged `Media` (agent tools only), and
|
|
# `openhuman::image` is currently unwired scaffold (added #2997).
|
|
media = []
|
|
# Flows domains: the `flows::` automation surface (saved tinyflows graphs —
|
|
# create/run/schedule + the workflow_builder / flow_discovery agents), the
|
|
# `tinyflows::` adapter seam, and the `rhai_workflows::` language-workflow tool.
|
|
# Default-ON — the desktop app always ships with Workflows. Slim / headless
|
|
# builds opt out via `--no-default-features --features "<list without flows>"`,
|
|
# which drops `tinyflows` + its `jaq-core`/`jaq-std`/`jaq-json` JSON-query stack
|
|
# and, via `tinyagents/repl`, the `rhai` scripting engine. Composes with the
|
|
# runtime `DomainSet::flows` flag (#4796): the feature narrows the compile-time
|
|
# surface, `DomainSet` gates it at runtime.
|
|
# NOTE: this gate does NOT drop `tinyagents` itself — 26+ domains consume it.
|
|
# Only its `repl` feature (⇒ `rhai`) is exclusive to flows.
|
|
flows = ["dep:tinyflows", "tinyagents/repl"]
|
|
# Meet domains: `meet` (join-URL validation), `meet_agent` (live STT/LLM/TTS
|
|
# loop over an open call), and `agent_meetings` (backend-delegated Meet bot via
|
|
# Socket.IO). Default-ON — the desktop app always ships with Meet. Slim /
|
|
# headless builds opt out via `--no-default-features --features "<list without
|
|
# meet>"`. Composes with the runtime `DomainSet::meet` flag (#4796): the feature
|
|
# narrows the compile-time surface, `DomainSet` gates it at runtime.
|
|
# NOTE: unlike `voice`, this gate drops NO dependencies — the Meet domains have
|
|
# zero exclusive crates. `meet_agent::wav` is a hand-rolled RIFF writer
|
|
# precisely so Meet never needed `hound` (which `voice` already owns), so the
|
|
# dependency shed was pre-paid. The gate's value is compile-time surface +
|
|
# binary size, not the dep tree.
|
|
# CARVE-OUT: `meet_agent::wav` stays compiled in ALL builds — the always-on
|
|
# `desktop_companion` STT path depends on it. See `meet_agent/mod.rs`.
|
|
meet = []
|
|
# Skills domains: `openhuman::skills` (metadata/discovery/install),
|
|
# `openhuman::skill_runtime` (SKILL.md execution + the skill_executor agent),
|
|
# and `openhuman::skill_registry` (remote catalogs + the skill_setup agent).
|
|
# Default-ON — the desktop app always ships with skills. Slim / headless builds
|
|
# opt out via `--no-default-features --features "<explicit list without skills>"`.
|
|
# Composes with the runtime `DomainSet::skills` flag (#4796): the feature
|
|
# narrows the compile-time surface, `DomainSet` gates it at runtime.
|
|
#
|
|
# The dep list is INTENTIONALLY EMPTY — do not "fix" it. Unlike `voice`
|
|
# (`hound`/`lettre`), these domains have no exclusive dependencies: every crate
|
|
# they touch (serde, serde_json, tokio, anyhow, async-trait, …) is shared with
|
|
# always-on domains, and `runtime_node`/`runtime_python` are used by Agent /
|
|
# Flows / Memory too. This gate's value is tool-surface + prompt-bloat +
|
|
# startup cost, NOT binary size.
|
|
#
|
|
# NOTE: `openhuman::skills::types` and `::ops_types` stay compiled even when
|
|
# this feature is OFF — `tools::traits` re-exports `ToolResult`/`ToolContent`
|
|
# out of `skills::types` and ~236 files consume them, so those inert serde
|
|
# types are a type carve-out, not part of the gated behaviour. See
|
|
# `src/openhuman/skills/stub.rs`.
|
|
skills = []
|
|
# MCP domains: `mcp_server` (the `openhuman mcp` stdio/HTTP server exposing our
|
|
# tool surface), `mcp_registry` (dynamic Smithery installs — SQLite, lifecycle,
|
|
# `mcp_clients` RPC namespace), `mcp_audit` (write-audit log), and the
|
|
# static/config-declared server set in `mcp_client`. Default-ON — the desktop
|
|
# app always ships with MCP. Composes with the runtime `DomainSet::mcp` flag
|
|
# (#4796): this feature narrows the compile-time surface, `DomainSet` gates it
|
|
# at runtime.
|
|
#
|
|
# INTENTIONALLY EMPTY — do NOT "fix" this by adding `dep:` entries. There is no
|
|
# MCP SDK in this crate: the whole protocol stack is hand-rolled over tokio
|
|
# process stdio + reqwest + axum, every one of which is load-bearing for
|
|
# non-MCP domains. So this gate drops ~20k LOC and ~19 agent tools but ZERO
|
|
# dependencies. The issue-level DoD line claiming it "sheds the MCP SDK /
|
|
# transport stack" is superseded by this correction (see AGENTS.md).
|
|
#
|
|
# NOTE: `mcp_client::{sanitize, client}` stay ALWAYS compiled — they are
|
|
# mis-housed shared utilities (the gitbooks docs tool dials `McpHttpClient`;
|
|
# the orchestrator prompt sanitises *skill* descriptions through
|
|
# `sanitize::sanitize_for_llm`). The gate follows the real dependency graph,
|
|
# not the directory name.
|
|
mcp = []
|
|
# Sentry crash/error reporting: the `sentry::init` guard + secret-scrubbing
|
|
# `before_send` hook (src/main.rs), the sentry-tracing bridge layer
|
|
# (core::logging), the ~24 `before_send` Event classifiers + the two
|
|
# `report_*_message` capture paths (core::observability), the session-boundary
|
|
# scope binding (credentials::sentry_scope), and the `openhuman sentry-test`
|
|
# CLI probe. Default-ON — the desktop app always ships with crash reporting.
|
|
# Slim / headless builds opt out via `--no-default-features --features
|
|
# "<explicit list without crash-reporting>"`, which drops the exclusive
|
|
# `sentry` dependency (and its transitive backtrace/contexts/panic/tracing/
|
|
# debug-images/reqwest/rustls stack) from the non-test build.
|
|
#
|
|
# TYPE CARVE-OUT (see AGENTS.md "Compile-time domain gates"): the sentry-free
|
|
# string classifiers (`is_transient_message_failure`,
|
|
# `is_insufficient_credits_message`, `contains_transient_transport_phrase`, …)
|
|
# and the `report_*_message` / `sentry_scope::{bind,clear}` signatures stay
|
|
# compiled in BOTH builds — only the `sentry::`-touching bodies are gated — so
|
|
# NO stub file is needed and always-on callers need no per-call `#[cfg]`. When
|
|
# off, `report_error_message`/`report_warning_message` still emit their
|
|
# `tracing::{error,warn}!` diagnostic, `sentry_tracing_layer()` degrades to a
|
|
# no-op `Identity` layer, and `openhuman sentry-test` returns a "built without
|
|
# the crash-reporting feature" error.
|
|
crash-reporting = ["dep:sentry"]
|
|
|
|
# Tabbed terminal UI: the `openhuman tui` (alias `chat`) CLI subcommand, a
|
|
# ratatui/crossterm front-end for logs, orchestrator chat, curated configuration,
|
|
# and account settings. Default-ON for the standalone `openhuman-core` binary, but
|
|
# INTENTIONALLY NOT forwarded to the desktop shell (the desktop app ships its own
|
|
# Tauri UI and never needs a terminal one) — see the allowlist entry in
|
|
# `scripts/ci/check-feature-forwarding.mjs`. Slim / headless builds opt out via
|
|
# `--no-default-features --features "<explicit list without tui>"`, which drops
|
|
# the exclusive `ratatui` + `crossterm` dependencies. The module
|
|
# `src/openhuman/tui/` is a facade (always compiled) whose behavioural submodules
|
|
# are `#[cfg(feature = "tui")]`; when off, `tui::stub::run_from_cli` returns a
|
|
# build-fact "tui feature disabled at compile time" error from the untouched
|
|
# `"tui" | "chat"` CLI arm (mirrors the `mcp` stub pattern).
|
|
tui = ["dep:ratatui", "dep:crossterm", "dep:unicode-width"]
|
|
# Local Medulla brain (plan Flavor A, §3.1–§3.2): the `medulla_local` domain —
|
|
# a supervised `medulla-serve` Node child speaking the serve NDJSON protocol,
|
|
# host-side inference + tools port callbacks, the `medulla_local` RPC namespace,
|
|
# and the subconscious-replacement draft (`subconscious.engine = "medulla"`,
|
|
# §5.2). Default-ON — the desktop app ships it — and therefore FORWARDED to the
|
|
# Tauri shell's `openhuman_core` features (default-features=false there). Slim /
|
|
# headless builds opt out via `--no-default-features --features "<list without
|
|
# medulla-local>"`. The module is `#[cfg(feature = "medulla-local")]` at its
|
|
# `pub mod` declaration (a registration-site gate, like `flows`); the
|
|
# `subconscious.engine` config field stays compiled in ALL builds (inert serde),
|
|
# and the subconscious tick's medulla branch is `#[cfg]`-gated so the default
|
|
# (`local`) path is byte-identical whether or not this feature is on.
|
|
# Sheds ZERO exclusive dependencies — tokio net/process, reqwest, serde are all
|
|
# load-bearing for other domains; the value is compile-time surface.
|
|
# The serve transport is unix-only (unix domain sockets): on non-unix targets
|
|
# (Windows desktop) the feature still compiles via a supervisor stub that
|
|
# reports a typed unsupported-platform error, so forwarding the default-ON
|
|
# gate to the Tauri shell never breaks Windows packaging.
|
|
medulla-local = []
|
|
|
|
# Channels domain: `openhuman::channels` (external-messaging providers — Telegram,
|
|
# Discord, Slack, Signal, WhatsApp, iMessage, IRC, … — plus the channel runtime,
|
|
# controllers, host, proactive messaging and inbound dispatch) together with the
|
|
# `webview_accounts` / `webview_apis` / `webview_notifications` / `whatsapp_data`
|
|
# webview-bridge domains. Default-ON — the desktop app always ships with
|
|
# channels. Slim / headless builds opt out via `--no-default-features --features
|
|
# "<explicit list without channels>"`. Composes with the runtime
|
|
# `DomainSet::Channels` flag (#4796): this feature narrows the compile-time
|
|
# surface, `DomainSet` gates it at runtime.
|
|
#
|
|
# INTENTIONALLY EMPTY — do NOT "fix" this by adding `dep:` entries. This gate
|
|
# sheds ZERO dependencies: `tinychannels` stays load-bearing regardless
|
|
# (`config/schema/channels.rs` re-exports its config types, `event_bus/events.rs`
|
|
# `DomainEvent` embeds `tinychannels::ChannelInboundEnvelope`, and
|
|
# `security/pairing.rs` re-exports its pairing helpers), so it is always
|
|
# compiled. The gate's value is compile-time surface + binary size, not the dep
|
|
# tree. (`whatsapp-web` refines this gate — see below — forwarding to the
|
|
# `tinychannels/whatsapp-web` provider feature.)
|
|
#
|
|
# NOTE: the in-app web chat (`openhuman::web_chat`, RPC namespace `channel`) is
|
|
# NOT gated by this feature even though its runtime tag is
|
|
# `DomainGroup::Channels` — it is core product surface and stays always
|
|
# compiled (decoupled from `channels/` in #5002). The `channels::{traits, cli}`
|
|
# carve-outs also stay ungated — `traits` is a 1-line tinychannels re-export and
|
|
# `cli::CliChannel` is the dep-free local REPL used by the always-on agent
|
|
# harness interactive loop. See AGENTS.md "channels gate" + `channels/mod.rs`.
|
|
channels = []
|
|
sandbox-landlock = ["dep:landlock"]
|
|
sandbox-bubblewrap = []
|
|
peripheral-rpi = ["dep:rppal"]
|
|
browser-native = ["dep:fantoccini"]
|
|
fantoccini = ["browser-native"]
|
|
landlock = ["sandbox-landlock"]
|
|
# The WhatsApp Web provider now lives in tinychannels; forward to its feature.
|
|
# It is a refinement INSIDE the `channels` gate — enabling it pulls in the whole
|
|
# channels domain (the provider re-exports live under `channels/providers/`).
|
|
whatsapp-web = ["channels", "tinychannels/whatsapp-web"]
|
|
# Exposes the destructive `openhuman.test_reset` RPC. Off by default; the E2E
|
|
# build (app/scripts/e2e-build.sh) flips it on. Shipped binaries never have
|
|
# this feature so the wipe RPC isn't even registered, let alone reachable.
|
|
e2e-test-support = []
|
|
# Builds the `rss-bench` benchmark binary (#5046). Default-OFF, so it is never
|
|
# part of the shipped desktop/library build and the feature-forwarding gate
|
|
# (which only inspects the `default` list) never requires forwarding it.
|
|
rss-bench = []
|
|
# Adds dhat heap profiling on top of `rss-bench` for the `library-profile`
|
|
# binary. Default-OFF, dev-only: installs dhat's global allocator, which
|
|
# perturbs RSS/timing numbers, so it is a separate opt-in feature rather than
|
|
# folded into `rss-bench`. Never forwarded to the shipped build.
|
|
rss-bench-dhat = ["rss-bench", "dep:dhat"]
|
|
|
|
[lints.rust]
|
|
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(coverage)'] }
|
|
|
|
# These project-wide shape/documentation lints describe intentional public APIs
|
|
# and long-standing module docs. Keep them explicitly baselined so `-D warnings`
|
|
# can make every other Clippy and rustc diagnostic a hard failure.
|
|
[lints.clippy]
|
|
borrowed_box = "allow"
|
|
doc_overindented_list_items = "allow"
|
|
field_reassign_with_default = "allow"
|
|
large_enum_variant = "allow"
|
|
result_large_err = "allow"
|
|
should_implement_trait = "allow"
|
|
too_many_arguments = "allow"
|
|
while_let_loop = "allow"
|
|
|
|
# Fix whisper-rs-sys CRT mismatch on Windows MSVC (LNK2038).
|
|
# Upstream cmake build defaults to /MD but Rust uses /MT.
|
|
# This fork adds config.static_crt(true) to the build script.
|
|
# See: https://github.com/tinyhumansai/openhuman/issues/273
|
|
[patch.crates-io]
|
|
whisper-rs-sys = { git = "https://github.com/tinyhumansai/whisper-rs-sys.git", branch = "main" }
|
|
# TinyAgents is vendored as a git submodule (pinned at the released tag) so
|
|
# migration work can change the SDK source in-tree, test it against OpenHuman
|
|
# immediately, and PR the diff upstream from the submodule. Keep the submodule
|
|
# version in lockstep with the `tinyagents` requirement above. After cloning:
|
|
# `git submodule update --init vendor/tinyagents` (worktrees included).
|
|
tinyagents = { path = "vendor/tinyagents" }
|
|
# TinyFlows, TinyCortex, TinyJuice, TinyChannels, and TinyPlace are vendored beside
|
|
# TinyAgents so integration work can test crate changes against OpenHuman before
|
|
# publishing.
|
|
tinyflows = { path = "vendor/tinyflows" }
|
|
tinycortex = { path = "vendor/tinycortex" }
|
|
tinyjuice = { path = "vendor/tinyjuice" }
|
|
tinychannels = { path = "vendor/tinychannels" }
|
|
tinyplace = { path = "vendor/tinyplace/sdk/rust" }
|
|
|
|
# Emit just enough DWARF in release builds for Sentry to symbolicate Rust
|
|
# panics + render surrounding source lines. `line-tables-only` keeps the
|
|
# binary small (only file+line tables, no full type info) while still
|
|
# letting `sentry-cli debug-files upload --include-sources` produce a
|
|
# usable `.src.zip`. `split-debuginfo = "packed"` writes the debug data
|
|
# into a separate `.dSYM` bundle on macOS so the shipped executable
|
|
# itself stays slim.
|
|
[profile.release]
|
|
debug = "line-tables-only"
|
|
split-debuginfo = "packed"
|
|
|
|
# Fast CI builds: trade runtime perf for compile speed
|
|
[profile.ci]
|
|
inherits = "release"
|
|
opt-level = 1
|
|
codegen-units = 16
|
|
lto = false
|
|
incremental = false
|
|
strip = true
|
|
debug = false
|
|
|
|
# Faster local + CI iteration (#3877): compile third-party dependencies in the
|
|
# dev/test profiles WITHOUT debuginfo. The dependency graph here is large (a
|
|
# local checkout showed root `target/` ~12G and Tauri `target/` ~4.4G), and
|
|
# DWARF generation + linking for every dependency is a dominant, repeated cost
|
|
# across `cargo build`, `cargo test`, `cargo clippy`, and `cargo llvm-cov`.
|
|
#
|
|
# Scope is intentionally narrow and low-risk:
|
|
# * `package."*"` targets dependencies only — our own crates keep full
|
|
# debuginfo, so panics/backtraces in OpenHuman code still resolve to
|
|
# file:line and a debugger can still step through our code.
|
|
# * Only the unoptimised `dev`/`test` profiles change. `release` and `ci`
|
|
# (which already set `debug = false` / `line-tables-only`) are untouched.
|
|
# * No artifact paths, features, or runtime behaviour change — this only
|
|
# reduces how much DWARF is emitted for dependencies, which also shrinks
|
|
# `target/` substantially.
|
|
[profile.dev.package."*"]
|
|
debug = false
|