Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
dd212eb
fix(core): give the JSON-RPC runtime a 16 MiB worker stack to survive…
sanil-23 Jun 1, 2026
d5d5a64
test: green the Rust Core Coverage suite (stale assertions + env-race…
sanil-23 Jun 1, 2026
b389418
Merge branch 'fix/subagent-stack-overflow' into fix/coverage-stale-tests
sanil-23 Jun 1, 2026
4f6f891
Merge remote-tracking branch 'upstream/main' into fix/coverage-stale-…
sanil-23 Jun 1, 2026
543b847
test(coverage): serialize env-racing raw-coverage tests with env_lock…
sanil-23 Jun 1, 2026
99276a3
Revert "test(coverage): serialize env-racing raw-coverage tests with …
sanil-23 Jun 1, 2026
c2af5bc
test: update stale composio-enabled count assertion (#3113 sync redes…
sanil-23 Jun 1, 2026
695bacc
test: make round21 github-reader hermetic + drop stale comments asser…
sanil-23 Jun 1, 2026
a1b5484
test: make github-reader tests hermetic in memory_sync_sources + near90
sanil-23 Jun 1, 2026
be29029
test: responses-API input content is structured parts, not a bare string
sanil-23 Jun 1, 2026
89c4325
test: fix time-bomb in cron-add coverage test (hardcoded past 'at' date)
sanil-23 Jun 1, 2026
13d9cbf
test: give ApprovalGate test session_ids the required `session-` prefix
sanil-23 Jun 1, 2026
494579f
Merge remote-tracking branch 'upstream/main' into fix/coverage-stale-…
sanil-23 Jun 1, 2026
0e46854
ci(coverage): serialize core llvm-cov tests (--test-threads=1)
sanil-23 Jun 1, 2026
657781a
test(coverage): hold env_lock in orchestrator_tool_synthesis (fast ra…
sanil-23 Jun 1, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .github/workflows/coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,10 @@ jobs:
- name: Install cargo-llvm-cov
uses: taiki-e/install-action@cargo-llvm-cov
- name: Run cargo llvm-cov for openhuman core
run: cargo llvm-cov -p openhuman --lcov --output-path lcov-core.info
# Single-threaded: several raw-coverage tests set the process-global
# OPENHUMAN_WORKSPACE per-test and trample each other under llvm-cov's
# slower instrumentation when run in parallel. Serialize for hermeticity.
run: cargo llvm-cov -p openhuman --lcov --output-path lcov-core.info -- --test-threads=1
- name: Upload core lcov
uses: actions/upload-artifact@v5
with:
Expand Down
7 changes: 6 additions & 1 deletion .github/workflows/pr-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,12 @@ jobs:
uses: taiki-e/install-action@cargo-llvm-cov

- name: Run cargo llvm-cov for openhuman core
run: bash scripts/ci-cancel-aware.sh cargo llvm-cov -p openhuman --lcov --output-path lcov-core.info
# Run the coverage suite single-threaded: several raw-coverage tests set
# the process-global OPENHUMAN_WORKSPACE env var per-test, and under
# llvm-cov's slower instrumentation the parallel default lets them
# trample each other's workspace (flaky count/state assertions). These
# tests are hermetic only when serialized.
run: bash scripts/ci-cancel-aware.sh cargo llvm-cov -p openhuman --lcov --output-path lcov-core.info -- --test-threads=1

- name: Upload core lcov
uses: actions/upload-artifact@v5
Expand Down
9 changes: 9 additions & 0 deletions src/core/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -278,8 +278,17 @@ fn run_server_command(args: &[String]) -> Result<()> {
crate::core::logging::init_for_cli_run(verbose, log_scope);

// Initialize the Tokio multi-threaded runtime.
//
// 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 (`subagent_runner::ops`), 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"), taking
// 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)
.build()?;
rt.block_on(async {
crate::core::jsonrpc::run_server(host.as_deref(), port, socketio_enabled).await
Expand Down
2 changes: 1 addition & 1 deletion tests/memory_raw_coverage_e2e.rs
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,7 @@ fn memory_sources_validation_and_sync_classification_edges() {
assert_eq!(classify_unknown("GMAIL_FETCH_EMAILS"), ToolScope::Read);
assert_eq!(
toolkit_from_slug(" MICROSOFT_TEAMS_SEND "),
Some("microsoft".into())
Some("microsoft_teams".into())
);
assert_eq!(toolkit_from_slug(""), None);
let catalog = [CuratedTool {
Expand Down
6 changes: 3 additions & 3 deletions tests/memory_threads_raw_coverage_e2e.rs
Original file line number Diff line number Diff line change
Expand Up @@ -989,7 +989,7 @@ fn memory_schema_registries_and_query_tool_metadata_cover_public_surfaces() {
let legacy_tree_schemas = openhuman_core::openhuman::memory::schema::all_controller_schemas();
let legacy_tree_controllers =
openhuman_core::openhuman::memory::schema::all_registered_controllers();
assert_eq!(legacy_tree_schemas.len(), 19);
assert_eq!(legacy_tree_schemas.len(), 21);
assert_eq!(legacy_tree_schemas.len(), legacy_tree_controllers.len());
for function in [
"ingest",
Expand Down Expand Up @@ -1208,7 +1208,7 @@ fn memory_sync_composio_catalog_scope_and_state_helpers_cover_edge_cases() {
assert_eq!(classify_unknown("GMAIL_FETCH_EMAILS"), ToolScope::Read);
assert_eq!(
toolkit_from_slug(" MICROSOFT_TEAMS_SEND_MESSAGE "),
Some("microsoft".into())
Some("microsoft_teams".into())
);
assert_eq!(toolkit_from_slug(""), None);
let catalog = &[CuratedTool {
Expand Down Expand Up @@ -3761,7 +3761,7 @@ async fn memory_sources_registry_rpc_and_schema_handlers_cover_crud_edges() {

let schemas = all_memory_sources_controller_schemas();
let controllers = all_memory_sources_registered_controllers();
assert_eq!(schemas.len(), 9);
assert_eq!(schemas.len(), 10);
assert_eq!(schemas.len(), controllers.len());
assert_eq!(
openhuman_core::openhuman::memory_sources::schemas::schemas("read_item").function,
Expand Down
2 changes: 1 addition & 1 deletion tests/memory_tree_sync_raw_coverage_e2e.rs
Original file line number Diff line number Diff line change
Expand Up @@ -458,7 +458,7 @@ async fn composio_providers_sync_state_and_bus_surfaces_cover_read_write_edges()
);
assert_eq!(
toolkit_from_slug("MICROSOFT_TEAMS_SEND_MESSAGE").as_deref(),
Some("microsoft")
Some("microsoft_teams")
);
assert_eq!(classify_unknown("GMAIL_DELETE_DRAFT"), ToolScope::Admin);
assert_eq!(classify_unknown("NOTION_CREATE_PAGE"), ToolScope::Write);
Expand Down
4 changes: 3 additions & 1 deletion tests/tools_agent_credentials_state_raw_coverage_e2e.rs
Original file line number Diff line number Diff line change
Expand Up @@ -655,7 +655,9 @@ async fn round16_spawn_subagent_tool_and_runner_error_success_paths() {
.await
.expect("dedicated thread returns tool result");
assert!(disabled_thread.is_error);
assert!(disabled_thread.output().contains("temporarily disabled"));
// The dedicated_thread flag no longer short-circuits with a "temporarily
// disabled" message (see spawn_subagent::dedicated_thread_flag_no_longer_returns_disabled_error).
assert!(!disabled_thread.output().contains("temporarily disabled"));

let provider = Arc::new(ScriptedProvider::new(vec![response(
Some("subagent final answer that will be clipped"),
Expand Down
4 changes: 3 additions & 1 deletion tests/tools_composio_network_leftovers_raw_coverage_e2e.rs
Original file line number Diff line number Diff line change
Expand Up @@ -592,7 +592,9 @@ async fn round20_spawn_subagent_covers_validation_schema_and_disabled_worker_bra
.await
.expect("dedicated thread disabled returns tool result");
assert!(dedicated_thread.is_error);
assert!(dedicated_thread.output().contains("temporarily disabled"));
// The dedicated_thread flag no longer short-circuits with a "temporarily
// disabled" message (see spawn_subagent::dedicated_thread_flag_no_longer_returns_disabled_error).
assert!(!dedicated_thread.output().contains("temporarily disabled"));
}

async fn start_loopback(app: Router) -> String {
Expand Down
Loading