From 9208578474d96c7d740f71aeb490e61fd6d7f20d Mon Sep 17 00:00:00 2001 From: Steven Enamakel Date: Wed, 7 Oct 2026 07:56:20 +0300 Subject: [PATCH 01/13] feat(config): add clone support for config types Added a Clone implementation for the config schema types so they can be duplicated when needed elsewhere in the core. Auto-committed-on: dragonfly Co-authored-by: Medulla --- .../src/config/schema/types/config_clone.rs | 192 ++++++++++++++++++ 1 file changed, 192 insertions(+) create mode 100644 crates/openhuman-core/src/config/schema/types/config_clone.rs diff --git a/crates/openhuman-core/src/config/schema/types/config_clone.rs b/crates/openhuman-core/src/config/schema/types/config_clone.rs new file mode 100644 index 00000000000..8ad139aadd8 --- /dev/null +++ b/crates/openhuman-core/src/config/schema/types/config_clone.rs @@ -0,0 +1,192 @@ +//! Hand-written `Clone` for [`Config`]. +//! +//! `#[derive(Clone)]` marks `clone` `#[inline]`, so every codegen unit and +//! every crate that clones a `Config` emits its own copy of this ~48 KiB +//! function: 17 copies in a release `openhuman-core`. `#[inline(never)]` +//! keeps exactly one. The struct literal lists every field, so adding a field +//! to `Config` without adding it here is a compile error, not a silent skip. + +use super::config::Config; + +impl Clone for Config { + #[inline(never)] + fn clone(&self) -> Self { + Self { + workspace_dir +action_dir +action_dir_override +files_dir_override +files_dir_history +config_path +cli_inference_snapshot +recovered_from_corruption +schema_version +api_url +api_key +inference_url +default_model +default_temperature +output_language +temperature_unsupported_models +dashboard +observability +autonomy +desktop +computer +hooks +privacy +sandbox +runtime +shell +web_chat +reliability +scheduler +scheduler_gate +agent +orchestrator +teams +context +model_routes +embedding_routes +cron +task_sources +channels_config +memory +composio +secrets +browser +http_request +curl +gitbooks +mcp_client +modules +capability_providers +multimodal +multimodal_files +seltz +searxng +web_search +search +proxy +cost +legacy_memory_sources +agent_registry +agents +local_ai +claude_agent_sdk +cloud_providers +primary_cloud +ephemeral_route +chat_provider +reasoning_provider +agentic_provider +coding_provider +vision_provider +memory_provider +embeddings_provider +custom_embeddings +node +runtime_python +runtime_pool +tokenjuice +hosting +voice_server +voice_providers +stt_provider +tts_provider +integrations +update +dictation +onboarding_completed +chat_onboarding_completed +model_registry: self.workspace_dir +action_dir +action_dir_override +files_dir_override +files_dir_history +config_path +cli_inference_snapshot +recovered_from_corruption +schema_version +api_url +api_key +inference_url +default_model +default_temperature +output_language +temperature_unsupported_models +dashboard +observability +autonomy +desktop +computer +hooks +privacy +sandbox +runtime +shell +web_chat +reliability +scheduler +scheduler_gate +agent +orchestrator +teams +context +model_routes +embedding_routes +cron +task_sources +channels_config +memory +composio +secrets +browser +http_request +curl +gitbooks +mcp_client +modules +capability_providers +multimodal +multimodal_files +seltz +searxng +web_search +search +proxy +cost +legacy_memory_sources +agent_registry +agents +local_ai +claude_agent_sdk +cloud_providers +primary_cloud +ephemeral_route +chat_provider +reasoning_provider +agentic_provider +coding_provider +vision_provider +memory_provider +embeddings_provider +custom_embeddings +node +runtime_python +runtime_pool +tokenjuice +hosting +voice_server +voice_providers +stt_provider +tts_provider +integrations +update +dictation +onboarding_completed +chat_onboarding_completed +model_registry.clone(), + } + } +} From 3d77761d826d99e94ee44be6df142186da58663a Mon Sep 17 00:00:00 2001 From: Steven Enamakel Date: Wed, 7 Oct 2026 07:56:31 +0300 Subject: [PATCH 02/13] feat(config): add clone support for config types Added a Clone implementation for the config schema types so they can be duplicated when needed elsewhere in the core. Auto-committed-on: dragonfly Co-authored-by: Medulla --- .../src/config/schema/types/config_clone.rs | 264 ++++++------------ 1 file changed, 88 insertions(+), 176 deletions(-) diff --git a/crates/openhuman-core/src/config/schema/types/config_clone.rs b/crates/openhuman-core/src/config/schema/types/config_clone.rs index 8ad139aadd8..ec693b79cb7 100644 --- a/crates/openhuman-core/src/config/schema/types/config_clone.rs +++ b/crates/openhuman-core/src/config/schema/types/config_clone.rs @@ -11,182 +11,94 @@ use super::config::Config; impl Clone for Config { #[inline(never)] fn clone(&self) -> Self { - Self { - workspace_dir -action_dir -action_dir_override -files_dir_override -files_dir_history -config_path -cli_inference_snapshot -recovered_from_corruption -schema_version -api_url -api_key -inference_url -default_model -default_temperature -output_language -temperature_unsupported_models -dashboard -observability -autonomy -desktop -computer -hooks -privacy -sandbox -runtime -shell -web_chat -reliability -scheduler -scheduler_gate -agent -orchestrator -teams -context -model_routes -embedding_routes -cron -task_sources -channels_config -memory -composio -secrets -browser -http_request -curl -gitbooks -mcp_client -modules -capability_providers -multimodal -multimodal_files -seltz -searxng -web_search -search -proxy -cost -legacy_memory_sources -agent_registry -agents -local_ai -claude_agent_sdk -cloud_providers -primary_cloud -ephemeral_route -chat_provider -reasoning_provider -agentic_provider -coding_provider -vision_provider -memory_provider -embeddings_provider -custom_embeddings -node -runtime_python -runtime_pool -tokenjuice -hosting -voice_server -voice_providers -stt_provider -tts_provider -integrations -update -dictation -onboarding_completed -chat_onboarding_completed -model_registry: self.workspace_dir -action_dir -action_dir_override -files_dir_override -files_dir_history -config_path -cli_inference_snapshot -recovered_from_corruption -schema_version -api_url -api_key -inference_url -default_model -default_temperature -output_language -temperature_unsupported_models -dashboard -observability -autonomy -desktop -computer -hooks -privacy -sandbox -runtime -shell -web_chat -reliability -scheduler -scheduler_gate -agent -orchestrator -teams -context -model_routes -embedding_routes -cron -task_sources -channels_config -memory -composio -secrets -browser -http_request -curl -gitbooks -mcp_client -modules -capability_providers -multimodal -multimodal_files -seltz -searxng -web_search -search -proxy -cost -legacy_memory_sources -agent_registry -agents -local_ai -claude_agent_sdk -cloud_providers -primary_cloud -ephemeral_route -chat_provider -reasoning_provider -agentic_provider -coding_provider -vision_provider -memory_provider -embeddings_provider -custom_embeddings -node -runtime_python -runtime_pool -tokenjuice -hosting -voice_server -voice_providers -stt_provider -tts_provider -integrations -update -dictation -onboarding_completed -chat_onboarding_completed -model_registry.clone(), + workspace_dir: self.workspace_dir.clone(), + action_dir: self.action_dir.clone(), + action_dir_override: self.action_dir_override.clone(), + files_dir_override: self.files_dir_override.clone(), + files_dir_history: self.files_dir_history.clone(), + config_path: self.config_path.clone(), + cli_inference_snapshot: self.cli_inference_snapshot.clone(), + recovered_from_corruption: self.recovered_from_corruption.clone(), + schema_version: self.schema_version.clone(), + api_url: self.api_url.clone(), + api_key: self.api_key.clone(), + inference_url: self.inference_url.clone(), + default_model: self.default_model.clone(), + default_temperature: self.default_temperature.clone(), + output_language: self.output_language.clone(), + temperature_unsupported_models: self.temperature_unsupported_models.clone(), + dashboard: self.dashboard.clone(), + observability: self.observability.clone(), + autonomy: self.autonomy.clone(), + desktop: self.desktop.clone(), + computer: self.computer.clone(), + hooks: self.hooks.clone(), + privacy: self.privacy.clone(), + sandbox: self.sandbox.clone(), + runtime: self.runtime.clone(), + shell: self.shell.clone(), + web_chat: self.web_chat.clone(), + reliability: self.reliability.clone(), + scheduler: self.scheduler.clone(), + scheduler_gate: self.scheduler_gate.clone(), + agent: self.agent.clone(), + orchestrator: self.orchestrator.clone(), + teams: self.teams.clone(), + context: self.context.clone(), + model_routes: self.model_routes.clone(), + embedding_routes: self.embedding_routes.clone(), + cron: self.cron.clone(), + task_sources: self.task_sources.clone(), + channels_config: self.channels_config.clone(), + memory: self.memory.clone(), + composio: self.composio.clone(), + secrets: self.secrets.clone(), + browser: self.browser.clone(), + http_request: self.http_request.clone(), + curl: self.curl.clone(), + gitbooks: self.gitbooks.clone(), + mcp_client: self.mcp_client.clone(), + modules: self.modules.clone(), + capability_providers: self.capability_providers.clone(), + multimodal: self.multimodal.clone(), + multimodal_files: self.multimodal_files.clone(), + seltz: self.seltz.clone(), + searxng: self.searxng.clone(), + web_search: self.web_search.clone(), + search: self.search.clone(), + proxy: self.proxy.clone(), + cost: self.cost.clone(), + legacy_memory_sources: self.legacy_memory_sources.clone(), + agent_registry: self.agent_registry.clone(), + agents: self.agents.clone(), + local_ai: self.local_ai.clone(), + claude_agent_sdk: self.claude_agent_sdk.clone(), + cloud_providers: self.cloud_providers.clone(), + primary_cloud: self.primary_cloud.clone(), + ephemeral_route: self.ephemeral_route.clone(), + chat_provider: self.chat_provider.clone(), + reasoning_provider: self.reasoning_provider.clone(), + agentic_provider: self.agentic_provider.clone(), + coding_provider: self.coding_provider.clone(), + vision_provider: self.vision_provider.clone(), + memory_provider: self.memory_provider.clone(), + embeddings_provider: self.embeddings_provider.clone(), + custom_embeddings: self.custom_embeddings.clone(), + node: self.node.clone(), + runtime_python: self.runtime_python.clone(), + runtime_pool: self.runtime_pool.clone(), + tokenjuice: self.tokenjuice.clone(), + hosting: self.hosting.clone(), + voice_server: self.voice_server.clone(), + voice_providers: self.voice_providers.clone(), + stt_provider: self.stt_provider.clone(), + tts_provider: self.tts_provider.clone(), + integrations: self.integrations.clone(), + update: self.update.clone(), + dictation: self.dictation.clone(), + onboarding_completed: self.onboarding_completed.clone(), + chat_onboarding_completed: self.chat_onboarding_completed.clone(), + model_registry: self.model_registry.clone(), } } } From a9671be2bc6c84140b2692d966b6053d799c5b9d Mon Sep 17 00:00:00 2001 From: Steven Enamakel Date: Wed, 7 Oct 2026 07:56:37 +0300 Subject: [PATCH 03/13] feat(config): add clone support for config types Added Clone implementations for the configuration schema types so they can be duplicated when needed elsewhere in the core. Auto-committed-on: dragonfly Co-authored-by: Medulla --- crates/openhuman-core/src/config/schema/types/config_clone.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/openhuman-core/src/config/schema/types/config_clone.rs b/crates/openhuman-core/src/config/schema/types/config_clone.rs index ec693b79cb7..efe0a5f3f19 100644 --- a/crates/openhuman-core/src/config/schema/types/config_clone.rs +++ b/crates/openhuman-core/src/config/schema/types/config_clone.rs @@ -11,6 +11,7 @@ use super::config::Config; impl Clone for Config { #[inline(never)] fn clone(&self) -> Self { + Self { workspace_dir: self.workspace_dir.clone(), action_dir: self.action_dir.clone(), action_dir_override: self.action_dir_override.clone(), From 99bf2b260c994fb0d9aa72e68f27b51f874e171e Mon Sep 17 00:00:00 2001 From: Steven Enamakel Date: Wed, 7 Oct 2026 07:56:40 +0300 Subject: [PATCH 04/13] feat(config): add schema types for config validation Introduce typed schema definitions for the configuration so values can be validated and described consistently. This lays the groundwork for surfacing config errors earlier and generating documentation from the schema. Auto-committed-on: dragonfly Co-authored-by: Medulla --- crates/openhuman-core/src/config/schema/types.rs | 1 + crates/openhuman-core/src/config/schema/types/config.rs | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/crates/openhuman-core/src/config/schema/types.rs b/crates/openhuman-core/src/config/schema/types.rs index 119292d68fc..0e7a0762a67 100644 --- a/crates/openhuman-core/src/config/schema/types.rs +++ b/crates/openhuman-core/src/config/schema/types.rs @@ -4,6 +4,7 @@ //! Load/save and env overrides extend `Config` in `load/`. mod config; +mod config_clone; mod defaults; mod model_ids; mod output_language; diff --git a/crates/openhuman-core/src/config/schema/types/config.rs b/crates/openhuman-core/src/config/schema/types/config.rs index 6b4ef6b4bc3..aa68e842f02 100644 --- a/crates/openhuman-core/src/config/schema/types/config.rs +++ b/crates/openhuman-core/src/config/schema/types/config.rs @@ -50,7 +50,9 @@ pub struct CustomEmbeddingsConfig { } /// Top-level configuration (config.toml root). -#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)] +/// +/// `Clone` is implemented by hand in `config_clone.rs` so it is emitted once. +#[derive(Debug, Serialize, Deserialize, JsonSchema)] pub struct Config { #[serde(skip)] pub workspace_dir: PathBuf, From d5d77adffdb494db2df8779d6778c1f8772a7d19 Mon Sep 17 00:00:00 2001 From: Steven Enamakel Date: Wed, 7 Oct 2026 07:57:07 +0300 Subject: [PATCH 05/13] perf(core): avoid cloning embedder config on read paths Add a CoreContext helper that borrows the current embedder config and hands a reference to a closure, then switch the workspace snapshot, gated-service check, and API-key probe to use it. These call sites only needed a single field or predicate, so the previous full Config clone was wasted work on every dispatch. Auto-committed-on: dragonfly Co-authored-by: Medulla --- crates/openhuman-core/src/config/schema/load/dirs.rs | 10 +++++++--- crates/openhuman-core/src/core/runtime/context.rs | 9 +++++++++ .../src/security/credentials/ops/gated_services.rs | 2 +- .../src/security/credentials/session_support.rs | 4 ++-- 4 files changed, 19 insertions(+), 6 deletions(-) diff --git a/crates/openhuman-core/src/config/schema/load/dirs.rs b/crates/openhuman-core/src/config/schema/load/dirs.rs index b0a8e57c334..4c6ff0cd3a4 100644 --- a/crates/openhuman-core/src/config/schema/load/dirs.rs +++ b/crates/openhuman-core/src/config/schema/load/dirs.rs @@ -332,9 +332,13 @@ pub async fn active_workspace_snapshot() -> Result<(PathBuf, u64)> { // mismatch there is not a wrong banner, it is *no* banner, permanently, // with only a `debug!` line to say so. See AGENTS.md, "CoreBuilder::config // alone configures boot and nothing else". - if let Some(config) = crate::core::runtime::context::CoreContext::current_embedder_config() { - let revision = super::active_workspace::publish_active_workspace(&config.workspace_dir); - return Ok((config.workspace_dir, revision)); + if let Some(workspace_dir) = + crate::core::runtime::context::CoreContext::with_current_embedder_config(|config| { + config.workspace_dir.clone() + }) + { + let revision = super::active_workspace::publish_active_workspace(&workspace_dir); + return Ok((workspace_dir, revision)); } let (default_openhuman_dir, default_workspace_dir) = default_config_and_workspace_dirs()?; let (_, workspace_dir, source) = diff --git a/crates/openhuman-core/src/core/runtime/context.rs b/crates/openhuman-core/src/core/runtime/context.rs index 3759a48ed49..14e05bce746 100644 --- a/crates/openhuman-core/src/core/runtime/context.rs +++ b/crates/openhuman-core/src/core/runtime/context.rs @@ -467,6 +467,15 @@ impl CoreContext { Self::current().and_then(|ctx| ctx.embedder_config.clone()) } + /// Read the embedder-supplied config for the current dispatch without + /// cloning it. Prefer this over [`Self::current_embedder_config`] when only + /// a field or a predicate is needed: a `Config` clone is a large copy. + pub fn with_current_embedder_config( + f: impl FnOnce(&crate::config::Config) -> R, + ) -> Option { + Self::current().and_then(|ctx| ctx.embedder_config.as_ref().map(f)) + } + /// Rebind the process default context to the current active user's /// workspace. Desktop login, logout, and pending-session revalidation can /// switch the active workspace after boot without rebuilding the core. diff --git a/crates/openhuman-core/src/security/credentials/ops/gated_services.rs b/crates/openhuman-core/src/security/credentials/ops/gated_services.rs index 7411393ba7c..6ed6fa01820 100644 --- a/crates/openhuman-core/src/security/credentials/ops/gated_services.rs +++ b/crates/openhuman-core/src/security/credentials/ops/gated_services.rs @@ -12,7 +12,7 @@ use crate::config::Config; /// that config's path and never touch the operator's global /// `~/.openhuman/active_user.toml` / `users/` tree. pub(super) fn is_embedder_host() -> bool { - crate::core::runtime::context::CoreContext::current_embedder_config().is_some() + crate::core::runtime::context::CoreContext::with_current_embedder_config(|_| ()).is_some() } /// Populate the process cache away from the next chat turn after startup or a diff --git a/crates/openhuman-core/src/security/credentials/session_support.rs b/crates/openhuman-core/src/security/credentials/session_support.rs index 9f91c456ad0..27d20d54e27 100644 --- a/crates/openhuman-core/src/security/credentials/session_support.rs +++ b/crates/openhuman-core/src/security/credentials/session_support.rs @@ -546,8 +546,8 @@ pub fn session_token_from_profile(profile: Option<&AuthProfile>) -> Option bool { - crate::core::runtime::CoreContext::current_embedder_config() - .is_some_and(|config| super::api_key::has_api_key(&config)) + crate::core::runtime::CoreContext::with_current_embedder_config(super::api_key::has_api_key) + .unwrap_or(false) } #[cfg(test)] From ed8cb2e5c9b4c0f4380fde477678c74f6d94cb84 Mon Sep 17 00:00:00 2001 From: Steven Enamakel Date: Wed, 7 Oct 2026 08:01:17 +0300 Subject: [PATCH 06/13] perf(core): box cross-crate async entry points to avoid duplicate monomorphization Wrap active_workspace_snapshot, agent_chat_for, and start_chat in #[inline(never)] functions returning BoxFuture, delegating to private async inner functions. Callers in openhuman-rpc and openhuman-embed previously re-instantiated each async body inside their own state machines, so boxing keeps a single compiled copy in this crate. Auto-committed-on: dragonfly Co-authored-by: Medulla --- .../src/config/schema/load/dirs.rs | 12 ++++++- .../inference/host_runtime/ops/agent_chat.rs | 31 ++++++++++++++++++- .../src/web_chat/ops/start_chat.rs | 31 ++++++++++++++++++- 3 files changed, 71 insertions(+), 3 deletions(-) diff --git a/crates/openhuman-core/src/config/schema/load/dirs.rs b/crates/openhuman-core/src/config/schema/load/dirs.rs index 4c6ff0cd3a4..87208616562 100644 --- a/crates/openhuman-core/src/config/schema/load/dirs.rs +++ b/crates/openhuman-core/src/config/schema/load/dirs.rs @@ -322,7 +322,17 @@ pub(crate) async fn resolve_runtime_config_dirs( /// revision separately: a switch between those two reads pairs workspace A /// with B's revision, and a receiver comparing revisions then ranks the stale /// A above the B it should yield to. -pub async fn active_workspace_snapshot() -> Result<(PathBuf, u64)> { +/// Returned boxed and `#[inline(never)]` on purpose: other crates await this +/// (`openhuman-rpc`, `openhuman-embed`), and an `async fn` body is otherwise +/// re-instantiated inside every calling crate's state machine. Boxing here +/// keeps one copy, compiled in this crate. +#[inline(never)] +pub fn active_workspace_snapshot( +) -> futures::future::BoxFuture<'static, Result<(PathBuf, u64)>> { + Box::pin(active_workspace_snapshot_inner()) +} + +async fn active_workspace_snapshot_inner() -> Result<(PathBuf, u64)> { // An embedding host that supplied its own `Config` is authoritative, and // `config::ops::load_config_with_timeout` already short-circuits on it for // exactly this reason. Resolving from disk/env here instead would answer diff --git a/crates/openhuman-core/src/inference/host_runtime/ops/agent_chat.rs b/crates/openhuman-core/src/inference/host_runtime/ops/agent_chat.rs index b4aa7160e3a..f819f959e27 100644 --- a/crates/openhuman-core/src/inference/host_runtime/ops/agent_chat.rs +++ b/crates/openhuman-core/src/inference/host_runtime/ops/agent_chat.rs @@ -219,8 +219,37 @@ fn build_turn_agent( /// thread. /// * The agent is built by `target`, so a library host can run one booted /// core with many independently defined agents. +/// +/// Returned boxed and `#[inline(never)]` on purpose: other crates await this +/// (`openhuman-rpc`, `openhuman-embed`), and an `async fn` body is otherwise +/// re-instantiated inside every calling crate's state machine. Boxing here +/// keeps one copy, compiled in this crate. +#[allow(clippy::too_many_arguments)] +#[inline(never)] +pub fn agent_chat_for<'a>( + config: &'a mut Config, + target: AgentChatTarget<'a>, + message: &'a str, + model_override: Option, + temperature: Option, + thread_id: Option, + cwd: Option, + route: Option, +) -> futures::future::BoxFuture<'a, Result, String>> { + Box::pin(agent_chat_for_inner( + config, + target, + message, + model_override, + temperature, + thread_id, + cwd, + route, + )) +} + #[allow(clippy::too_many_arguments)] -pub async fn agent_chat_for( +async fn agent_chat_for_inner( config: &mut Config, target: AgentChatTarget<'_>, message: &str, diff --git a/crates/openhuman-core/src/web_chat/ops/start_chat.rs b/crates/openhuman-core/src/web_chat/ops/start_chat.rs index b082978eead..64b72552fd0 100644 --- a/crates/openhuman-core/src/web_chat/ops/start_chat.rs +++ b/crates/openhuman-core/src/web_chat/ops/start_chat.rs @@ -131,7 +131,36 @@ fn prompt_guard_user_message(action: PromptEnforcementAction) -> &'static str { } } -pub async fn start_chat( +/// Returned boxed and `#[inline(never)]` on purpose: other crates await this +/// (`openhuman-rpc`, `openhuman-embed`), and an `async fn` body is otherwise +/// re-instantiated inside every calling crate's state machine. Boxing here +/// keeps one copy, compiled in this crate. +#[allow(clippy::too_many_arguments)] +#[inline(never)] +pub fn start_chat<'a>( + client_id: &'a str, + thread_id: &'a str, + message: &'a str, + model_override: Option, + temperature: Option, + locale: Option, + queue_mode: Option, + metadata: ChatRequestMetadata, +) -> futures::future::BoxFuture<'a, Result> { + Box::pin(start_chat_inner( + client_id, + thread_id, + message, + model_override, + temperature, + locale, + queue_mode, + metadata, + )) +} + +#[allow(clippy::too_many_arguments)] +async fn start_chat_inner( client_id: &str, thread_id: &str, message: &str, From eb880d64419e67cebe952976d1f55a7081cfa9a9 Mon Sep 17 00:00:00 2001 From: Steven Enamakel Date: Wed, 7 Oct 2026 08:04:28 +0300 Subject: [PATCH 07/13] docs(agents): note codegen unit tradeoff for release builds Release build guidance now records that 16 codegen units are used instead of one, since a single unit added 82% build time (#5595). Auto-committed-on: dragonfly Co-authored-by: Medulla --- AGENTS.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 08bebbd78f0..bfeaeb4bdaf 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -120,8 +120,8 @@ Keep matching profile settings synchronized between `Cargo.toml` and `crates/openhuman-app/Cargo.toml`: - Development dependencies use `debug = false`. -- Release builds use thin LTO, one codegen unit, symbol stripping, and - `debug = "line-tables-only"`. +- Release builds use thin LTO, 16 codegen units (one unit cost +82% build + time, #5595), symbol stripping, and `debug = "line-tables-only"`. ## Testing and CI From a376f8c3d9b2195f3b9deda2a06e5f99746b9d6e Mon Sep 17 00:00:00 2001 From: Steven Enamakel Date: Wed, 7 Oct 2026 08:04:49 +0300 Subject: [PATCH 08/13] chore(docs): add agent guidance to AGENTS.md Document the project's conventions and working expectations in AGENTS.md so automated agents and contributors have a single reference for how changes should be made. Auto-committed-on: dragonfly Co-authored-by: Medulla --- AGENTS.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index bfeaeb4bdaf..74b1b5dc964 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -120,8 +120,9 @@ Keep matching profile settings synchronized between `Cargo.toml` and `crates/openhuman-app/Cargo.toml`: - Development dependencies use `debug = false`. -- Release builds use thin LTO, 16 codegen units (one unit cost +82% build - time, #5595), symbol stripping, and `debug = "line-tables-only"`. +- Release builds use thin LTO, 16 codegen units (one unit pushed the desktop + release matrix from ~46 to ~84 min, 6941b18c85), symbol stripping, and + `debug = "line-tables-only"`. ## Testing and CI From 7aa7caafc7522bace5ca266bd2f75cd0adfb2aaa Mon Sep 17 00:00:00 2001 From: Steven Enamakel Date: Wed, 7 Oct 2026 08:23:15 +0300 Subject: [PATCH 09/13] build(ci): use mold and ICF for Linux desktop builds Install mold in the Linux build dependencies and set per-target RUSTFLAGS to link with mold and fold byte-identical functions via --icf=safe. The release profile's codegen units leave many duplicate functions that MSVC and Apple's linker already deduplicate but GNU ld does not, so this shrinks the stripped binary by roughly 2 MiB. Auto-committed-on: dragonfly Co-authored-by: Medulla --- .github/workflows/build-desktop.yml | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-desktop.yml b/.github/workflows/build-desktop.yml index 19bbdadc9fd..14bffe55cca 100644 --- a/.github/workflows/build-desktop.yml +++ b/.github/workflows/build-desktop.yml @@ -218,7 +218,7 @@ jobs: libnss3 libnspr4 libatk1.0-0 libatk-bridge2.0-0 libcups2 libdrm2 \ libxkbcommon0 libxcomposite1 libxdamage1 libxfixes3 libxrandr2 \ libgbm1 libpango-1.0-0 libcairo2 libatspi2.0-0 libxshmfence1 libu2f-udev \ - xvfb dbus dbus-x11 + xvfb dbus dbus-x11 mold command -v xdg-mime >/dev/null 2>&1 \ || { echo "::error::xdg-mime is still missing after installing xdg-utils"; exit 1; } # NOTE: The post-build dump lives further down (after `cargo tauri build`) @@ -431,6 +431,16 @@ jobs: TAURI_CONFIG_OVERRIDE: ${{ steps.config-overrides.outputs.json }} MATRIX_ARGS: ${{ matrix.settings.args }} PROFILE_FLAG: ${{ inputs.build_profile == 'debug' && '--debug' || '' }} + # Linux only: link with mold and fold byte-identical functions. The + # release profile's 16 codegen units and cross-crate instantiation + # leave many identical copies of the same function; MSVC already + # folds them (/OPT:ICF) and Apple's ld deduplicates by default, GNU ld + # cannot. `safe` only folds functions whose address is never taken, + # so C code comparing function pointers (sqlite) is unaffected. + # Measured on openhuman-core: 99.9 -> 97.6 MiB stripped. Per-target + # variables only reach the `--target` build, never build scripts. + CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUSTFLAGS: -C link-arg=-fuse-ld=mold -C link-arg=-Wl,--icf=safe + CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_RUSTFLAGS: -C link-arg=-fuse-ld=mold -C link-arg=-Wl,--icf=safe run: | # Inline NODE_OPTIONS so it reaches the vite child spawned by # beforeBuildCommand. Step-level env was observed not to propagate From 5292ccc763e4ea5cea713c0a59570b7635d4fa2c Mon Sep 17 00:00:00 2001 From: Steven Enamakel Date: Wed, 7 Oct 2026 08:23:47 +0300 Subject: [PATCH 10/13] chore: files changed crates/openhuman-core/src/core/runtime/context_tests.rs Auto-committed-on: dragonfly Co-authored-by: Medulla --- .../src/core/runtime/context_tests.rs | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/crates/openhuman-core/src/core/runtime/context_tests.rs b/crates/openhuman-core/src/core/runtime/context_tests.rs index 6d07b63fe2a..fce468b7b07 100644 --- a/crates/openhuman-core/src/core/runtime/context_tests.rs +++ b/crates/openhuman-core/src/core/runtime/context_tests.rs @@ -84,6 +84,27 @@ async fn the_current_dispatch_sees_the_scoped_embedder_config() { assert_eq!(scoped.workspace_dir, PathBuf::from("/tmp/scoped-ws")); } +#[tokio::test] +async fn the_current_embedder_config_can_be_read_without_cloning_it() { + // `with_current_embedder_config` is the borrow-only twin of + // `current_embedder_config`: same scoped config, projected through a closure. + let mut config = crate::config::Config::default(); + config.workspace_dir = PathBuf::from("/tmp/borrowed-ws"); + + let read = CoreContext::scope(ctx_with_config(config), async { + CoreContext::with_current_embedder_config(|c| c.workspace_dir.clone()) + }) + .await; + assert_eq!(read, Some(PathBuf::from("/tmp/borrowed-ws"))); + + // Without an embedder config the closure never runs. + let none = CoreContext::scope(ctx("/tmp/no-embedder-ws"), async { + CoreContext::with_current_embedder_config(|_| panic!("no config to read")) + }) + .await; + assert_eq!(none, None::<()>); +} + // ---- derived per-agent contexts (the multi-agent library seam) ----------- // // `derive_with` is how one booted runtime hosts many independently configured From cf8e38310651fd8aabe1467039a3456ff1bce3bf Mon Sep 17 00:00:00 2001 From: Steven Enamakel Date: Wed, 7 Oct 2026 08:23:56 +0300 Subject: [PATCH 11/13] feat(config): add clone support for config schema types Added Clone implementations for the config schema types so they can be duplicated when needed. This makes it possible to snapshot or pass around configuration values without moving them. Auto-committed-on: dragonfly Co-authored-by: Medulla --- .../src/config/schema/types/config_clone.rs | 4 +++ .../config/schema/types/config_clone_tests.rs | 31 +++++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 crates/openhuman-core/src/config/schema/types/config_clone_tests.rs diff --git a/crates/openhuman-core/src/config/schema/types/config_clone.rs b/crates/openhuman-core/src/config/schema/types/config_clone.rs index efe0a5f3f19..c7c00d7dd75 100644 --- a/crates/openhuman-core/src/config/schema/types/config_clone.rs +++ b/crates/openhuman-core/src/config/schema/types/config_clone.rs @@ -103,3 +103,7 @@ impl Clone for Config { } } } + +#[cfg(test)] +#[path = "config_clone_tests.rs"] +mod tests; diff --git a/crates/openhuman-core/src/config/schema/types/config_clone_tests.rs b/crates/openhuman-core/src/config/schema/types/config_clone_tests.rs new file mode 100644 index 00000000000..bdffc514592 --- /dev/null +++ b/crates/openhuman-core/src/config/schema/types/config_clone_tests.rs @@ -0,0 +1,31 @@ +use super::*; +use std::path::PathBuf; + +#[test] +fn clone_copies_every_serialized_field() { + let mut config = Config::default(); + config.workspace_dir = PathBuf::from("/tmp/clone-ws"); + config.default_model = Some("clone-model".into()); + config.chat_onboarding_completed = true; + + let cloned = config.clone(); + + assert_eq!(cloned.workspace_dir, config.workspace_dir); + assert_eq!(cloned.default_model, config.default_model); + assert!(cloned.chat_onboarding_completed); + assert_eq!( + serde_json::to_value(&cloned).expect("cloned config serializes"), + serde_json::to_value(&config).expect("config serializes"), + ); +} + +#[test] +fn clone_is_independent_of_the_original() { + let config = Config { + default_model: Some("before".into()), + ..Config::default() + }; + let mut cloned = config.clone(); + cloned.default_model = Some("after".into()); + assert_eq!(config.default_model.as_deref(), Some("before")); +} From 7b1f4fea18c506253e801df360b40c2640df5ff1 Mon Sep 17 00:00:00 2001 From: Steven Enamakel Date: Wed, 7 Oct 2026 08:28:11 +0300 Subject: [PATCH 12/13] refactor(config): drop redundant clone calls in Config clone impl The manual Clone implementation for Config called clone on fields that are already Copy, so those calls were replaced with direct copies. This removes needless work and quiets clippy's clone-on-copy lint without changing any behaviour. Auto-committed-on: dragonfly Co-authored-by: Medulla --- .../src/config/schema/types/config_clone.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/crates/openhuman-core/src/config/schema/types/config_clone.rs b/crates/openhuman-core/src/config/schema/types/config_clone.rs index c7c00d7dd75..e54ecffbae1 100644 --- a/crates/openhuman-core/src/config/schema/types/config_clone.rs +++ b/crates/openhuman-core/src/config/schema/types/config_clone.rs @@ -19,13 +19,13 @@ impl Clone for Config { files_dir_history: self.files_dir_history.clone(), config_path: self.config_path.clone(), cli_inference_snapshot: self.cli_inference_snapshot.clone(), - recovered_from_corruption: self.recovered_from_corruption.clone(), - schema_version: self.schema_version.clone(), + recovered_from_corruption: self.recovered_from_corruption, + schema_version: self.schema_version, api_url: self.api_url.clone(), api_key: self.api_key.clone(), inference_url: self.inference_url.clone(), default_model: self.default_model.clone(), - default_temperature: self.default_temperature.clone(), + default_temperature: self.default_temperature, output_language: self.output_language.clone(), temperature_unsupported_models: self.temperature_unsupported_models.clone(), dashboard: self.dashboard.clone(), @@ -34,7 +34,7 @@ impl Clone for Config { desktop: self.desktop.clone(), computer: self.computer.clone(), hooks: self.hooks.clone(), - privacy: self.privacy.clone(), + privacy: self.privacy, sandbox: self.sandbox.clone(), runtime: self.runtime.clone(), shell: self.shell.clone(), @@ -97,8 +97,8 @@ impl Clone for Config { integrations: self.integrations.clone(), update: self.update.clone(), dictation: self.dictation.clone(), - onboarding_completed: self.onboarding_completed.clone(), - chat_onboarding_completed: self.chat_onboarding_completed.clone(), + onboarding_completed: self.onboarding_completed, + chat_onboarding_completed: self.chat_onboarding_completed, model_registry: self.model_registry.clone(), } } From 589eb408628fbbfc37787519fee4747a6729d854 Mon Sep 17 00:00:00 2001 From: Steven Enamakel Date: Wed, 7 Oct 2026 08:28:34 +0300 Subject: [PATCH 13/13] style: reformat active_workspace_snapshot signature onto one line Auto-committed-on: dragonfly Co-authored-by: Medulla --- crates/openhuman-core/src/config/schema/load/dirs.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/crates/openhuman-core/src/config/schema/load/dirs.rs b/crates/openhuman-core/src/config/schema/load/dirs.rs index 87208616562..ae783a38d26 100644 --- a/crates/openhuman-core/src/config/schema/load/dirs.rs +++ b/crates/openhuman-core/src/config/schema/load/dirs.rs @@ -327,8 +327,7 @@ pub(crate) async fn resolve_runtime_config_dirs( /// re-instantiated inside every calling crate's state machine. Boxing here /// keeps one copy, compiled in this crate. #[inline(never)] -pub fn active_workspace_snapshot( -) -> futures::future::BoxFuture<'static, Result<(PathBuf, u64)>> { +pub fn active_workspace_snapshot() -> futures::future::BoxFuture<'static, Result<(PathBuf, u64)>> { Box::pin(active_workspace_snapshot_inner()) }