mirror of
https://github.com/tinyhumansai/openhuman.git
synced 2026-07-27 21:08:00 +00:00
This commit is contained in:
@@ -1821,21 +1821,27 @@ pub fn run() {
|
||||
// burns through the same 2 MB. In `crahs.log` (2026-05-17, build
|
||||
// 0.53.49) that tower plus the serde-monomorphised `Config` Visitor
|
||||
// frames pushed past the guard page and aborted with
|
||||
// `SIGBUS / KERN_PROTECTION_FAILURE`. The structural fix
|
||||
// (`spawn_blocking` for the TOML parse + cache in
|
||||
// `src/openhuman/config/{schema/load.rs, ops.rs}`) moves the
|
||||
// largest contributor off the worker; bumping the worker stack
|
||||
// itself gives the rest of the tower comfortable headroom so future
|
||||
// additions don't immediately re-tip the same scale. 8 MiB matches
|
||||
// the OS-default pthread main-thread stack on macOS, so we can
|
||||
// assume "as much room as the main thread" everywhere.
|
||||
// `SIGBUS / KERN_PROTECTION_FAILURE`.
|
||||
//
|
||||
// The structural fix (`spawn_blocking` for the TOML parse + cache in
|
||||
// `src/openhuman/config/{schema/load.rs, ops.rs}`) moves the largest
|
||||
// contributor off the worker. An initial 8 MiB bump shipped here was
|
||||
// enough for that single tower, but sub-agent delegation (issue #3159
|
||||
// / PR #3155) re-tipped the scale: the standalone `openhuman-core`
|
||||
// CLI server still aborted with `Abort trap: 6 / fatal runtime error:
|
||||
// stack overflow` once an orchestrator delegated. PR #3155 raised the
|
||||
// standalone server to 16 MiB; the desktop Tauri host is the *same*
|
||||
// tower running on a *different* runtime and needs the same headroom.
|
||||
// Share the constant with the rest of `src/core/*` via
|
||||
// [`openhuman_core::core::runtime::AGENT_WORKER_STACK_BYTES`] so all
|
||||
// multi-thread runtimes that may host an agent turn stay in sync.
|
||||
//
|
||||
// Must happen before any `tauri::async_runtime::*` call, otherwise
|
||||
// `set(...)` panics with "runtime already initialized".
|
||||
{
|
||||
let custom_runtime = tokio::runtime::Builder::new_multi_thread()
|
||||
.enable_all()
|
||||
.thread_stack_size(8 * 1024 * 1024)
|
||||
.thread_stack_size(openhuman_core::core::runtime::AGENT_WORKER_STACK_BYTES)
|
||||
.build()
|
||||
.expect("build custom tokio runtime for tauri async surface");
|
||||
let handle = custom_runtime.handle().clone();
|
||||
|
||||
@@ -122,6 +122,7 @@ fn run_dump_all(args: &[String]) -> Result<()> {
|
||||
|
||||
let rt = tokio::runtime::Builder::new_multi_thread()
|
||||
.enable_all()
|
||||
.thread_stack_size(crate::core::runtime::AGENT_WORKER_STACK_BYTES)
|
||||
.build()?;
|
||||
log::debug!("[agent-cli] run_dump_all: calling dump_all_agent_prompts");
|
||||
let dumps = rt.block_on(async {
|
||||
@@ -253,6 +254,7 @@ fn run_dump_prompt(args: &[String]) -> Result<()> {
|
||||
|
||||
let rt = tokio::runtime::Builder::new_multi_thread()
|
||||
.enable_all()
|
||||
.thread_stack_size(crate::core::runtime::AGENT_WORKER_STACK_BYTES)
|
||||
.build()?;
|
||||
log::debug!("[agent-cli] run_dump_prompt: calling dump_agent_prompt");
|
||||
let dumped = rt.block_on(async { dump_agent_prompt(options).await })?;
|
||||
|
||||
+7
-1
@@ -288,7 +288,7 @@ fn run_server_command(args: &[String]) -> Result<()> {
|
||||
// the JSON-RPC server down mid-request. Give workers a roomier stack.
|
||||
let rt = tokio::runtime::Builder::new_multi_thread()
|
||||
.enable_all()
|
||||
.thread_stack_size(16 * 1024 * 1024)
|
||||
.thread_stack_size(crate::core::runtime::AGENT_WORKER_STACK_BYTES)
|
||||
.build()?;
|
||||
rt.block_on(async {
|
||||
crate::core::jsonrpc::run_server(host.as_deref(), port, socketio_enabled).await
|
||||
@@ -337,8 +337,11 @@ fn run_call_command(args: &[String]) -> Result<()> {
|
||||
let method = method.ok_or_else(|| anyhow::anyhow!("--method is required"))?;
|
||||
let params = parse_json_params(¶ms).map_err(anyhow::Error::msg)?;
|
||||
|
||||
// `call` invokes a JSON-RPC method that may run an orchestrator turn
|
||||
// (e.g. `agent.chat`), so it needs the same roomy stack as the server.
|
||||
let rt = tokio::runtime::Builder::new_multi_thread()
|
||||
.enable_all()
|
||||
.thread_stack_size(crate::core::runtime::AGENT_WORKER_STACK_BYTES)
|
||||
.build()?;
|
||||
let value = rt
|
||||
.block_on(async { invoke_method(default_state(), &method, params).await })
|
||||
@@ -415,8 +418,11 @@ fn run_namespace_command(
|
||||
let method = all::rpc_method_from_parts(namespace, function)
|
||||
.ok_or_else(|| anyhow::anyhow!("unregistered controller '{namespace}.{function}'"))?;
|
||||
|
||||
// Same as the explicit `call` path above — any registered controller may
|
||||
// ultimately drive an orchestrator turn.
|
||||
let rt = tokio::runtime::Builder::new_multi_thread()
|
||||
.enable_all()
|
||||
.thread_stack_size(crate::core::runtime::AGENT_WORKER_STACK_BYTES)
|
||||
.build()?;
|
||||
let value = rt
|
||||
.block_on(async { invoke_method(default_state(), &method, Value::Object(params)).await })
|
||||
|
||||
@@ -20,6 +20,7 @@ pub mod logging;
|
||||
pub mod memory_cli;
|
||||
pub mod observability;
|
||||
pub mod rpc_log;
|
||||
pub mod runtime;
|
||||
pub mod shutdown;
|
||||
pub mod socketio;
|
||||
pub mod types;
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
//! Shared tokio runtime tuning constants.
|
||||
//!
|
||||
//! A single agent turn is a very large async state machine (system prompt +
|
||||
//! hundreds of tool specs + the nested provider/tool loop), and delegating
|
||||
//! to a sub-agent runs another full turn one level down. Even with the inner
|
||||
//! sub-agent future boxed, that nesting overflows tokio's default 2 MiB
|
||||
//! worker-thread stack and aborts the whole process (SIGABRT:
|
||||
//! "thread 'tokio-rt-worker' has overflowed its stack").
|
||||
//!
|
||||
//! PR #3155 set this on the standalone `openhuman-core run` JSON-RPC server.
|
||||
//! Issue #3159 calls out that every other multi-thread runtime that can host
|
||||
//! an agent turn (the desktop Tauri host's runtime, `agent_cli`, the rest of
|
||||
//! `cli.rs`, …) shares the same exposure. Centralising the value keeps them
|
||||
//! in sync; downstream call sites should set `.thread_stack_size(AGENT_WORKER_STACK_BYTES)`
|
||||
//! on every multi-thread runtime that may host an agent turn.
|
||||
pub const AGENT_WORKER_STACK_BYTES: usize = 16 * 1024 * 1024;
|
||||
Reference in New Issue
Block a user