Skip to content

refactor(orchestration,cron): pass the DispatchCtx to running-subagent, busy and completion readers (#7801) - #7862

Merged
senamakel merged 60 commits into
tinyhumansai:mainfrom
senamakel:fu-7801e-6
Oct 15, 2026
Merged

senamakel merged 60 commits into
tinyhumansai:mainfrom
senamakel:fu-7801e-6

Conversation

@senamakel

Copy link
Copy Markdown
Member

Summary

Part of #7801 (child of #7523): moves the running-subagent state and the next batch of current_tenant() / profile_key() readers off the ambient CoreContext and onto an explicit &DispatchCtx. No behaviour change intended: an explicit context resolves to exactly what the ambient read returned.

  • Running sub-agents (running_subagents/*): admit_spawn, register, owner_key, control_admits, admit_workspace, resolve, wait, steer, steer_control, roster, cancel_*, caller_workspace all take a ctx. Tools use dispatch_ctx_for_tool / the run context's dispatch_ctx(); the RPC controls and thread delete/purge/stop use the handler's ctx.
  • profile_key() is gone. tenant::profile_key_in(&Tenant, id) replaces it. The background-completion maps (background_completions), busy_guard::TurnBusy / is_busy / clear_busy_for_thread, and the DeliverySlot key from the caller's context. CompletionTarget captures the spawning context so a detached child records its completion under its own tenant (it runs on a spawned task). completion_owners::note, recover_on_boot/open, run_drain take the ctx.
  • Other current_tenant() readers: relay inbound (channel_relay_inbound) and turn_gate::acquire, cron completion owner / origin delivery / deliver_* / cron_run / run_job_now, session_store::current / current_agent_key_or, the devices bus and devices_create_pairing.
  • CronJob Run Now: the background task cron_run spawns now carries the caller's context (it ran on a bare tokio::spawn with no scope before, so in SaaS the delivery saw no tenant). Embed's Cron holds the runtime's context for run_now.
  • Extracted background_completions/thread_index.rs, background_delivery/slot.rs and two test modules so the touched files stay under the layout limit. No process static moved (delivering() stays in background_delivery.rs).

Merged upstream/main (including #7859, which reworked the origin transcript store): kept its agent_key_for / origin_transcripts and threaded the ctx into deliver_to_origin.

Tests

New regression tests (sibling *_tests.rs), each with no ambient scope anywhere and across awaits / spawned tasks / join!:

  • running_subagents_tenant_tests::saas_controls_follow_the_explicit_context_not_the_tasks_scope (SaaS child process): a worker is reachable through its own profile's context and refused through another's; each cancel removes only its own worker.
  • background_completions_tenant_tests::the_explicit_context_keys_completions_without_any_ambient_scope: two profiles on the same thread id never see each other's queue, stop or session index.
  • background_delivery_tenant_tests::busy_marks_are_keyed_by_the_explicit_context: busy marks and Stop are per-profile.
  • cron::completion_owner_tests::the_explicit_context_names_the_owner_with_no_task_scope.

Existing tenant tests were pinned to the ambient read: control() now passes DispatchCtx::ambient() (as the RPC server builds it from the scope), and two helpers that evaluated DispatchCtx::ambient() outside CoreContext::scope now pass DispatchCtx::new(ctx).

  • cargo test -p openhuman --lib: 9526 passed, 1 failed (memory::lifecycle::prefetch::tests::slow_engine_results_survive_the_manual_pre_turn_cutoff, a timing test, passes alone, untouched code).
  • saas_mode_e2e (19), saas_profile_isolation_e2e (3), embed saas_profiles (1), agent_lifecycle, flow_approvals pass. cron_host_delivery is the known pre-existing embed failure.
  • Not run: json_rpc_e2e.

Gates

cargo check default and --workspace --all-targets; product features (product-features.sh --core) all targets; --no-default-features -p openhuman; app manifest; cargo build -p openhuman-cli --bin openhuman-core; pnpm rust:layout; agent-runtime boundary (baseline untouched); process statics. scripts/ci/check-saas-ambient.mjs reports sites in files this PR does not touch, same as upstream main.

Refs #7801, #7523

Refresh the vendored tinyagents and tinybox dependencies to their current
revisions.

Auto-committed-on: dragonfly
The tinybus vendored dependency is no longer used now that the event bus
has been replaced by the in-tree implementation, so the submodule entry
was dropped to keep the vendor tree clean.

Auto-committed-on: dragonfly
Cancellation, registry, resolve, roster, steering, and wait paths for
running subagents were reworked so that cancelling a subagent reliably
stops it and waiting observes the correct terminal state. The vendored
tinycomputer dependency was updated to match.

Auto-committed-on: dragonfly
Vendors the tinyhumans SDK so the project can depend on it without
pulling it from an external source at build time.

Auto-committed-on: dragonfly
Deleting a thread now also tears down any subagent sessions it spawned, so
their runtime state and control handles do not outlive the parent thread.
Previously these sessions were left behind and could keep running after the
thread was gone.

Auto-committed-on: dragonfly
The channel_ops module in the web chat ops directory is no longer
referenced anywhere, so it has been deleted to keep the crate tidy.

Auto-committed-on: dragonfly
Adds a tool that spawns a subagent asynchronously and returns immediately
so the parent agent can continue working while the child runs. This lets
orchestration fan out work without blocking on each subagent's completion.

Auto-committed-on: dragonfly
Adds orchestration tools that let an agent close a running subagent, send it steering input, and wait for it to finish. These give the parent agent explicit control over subagent lifecycle instead of relying on implicit completion.

Auto-committed-on: dragonfly
Background completions now record which owner is responsible for each
completion, and subagent control consults that ownership when routing
results. This prevents completions from being delivered to the wrong
target when multiple owners are active.

Auto-committed-on: dragonfly
Adds a tool that spawns subagents asynchronously and executes them, letting
orchestration hand off work without blocking the caller. The vendored tinymcp
dependency is updated to support the new execution path.

Auto-committed-on: dragonfly
Refresh the vendored tinymemory and tinysearch dependencies to their
current upstream revisions.

Auto-committed-on: dragonfly
Vendors the tinyagents library so the project can rely on it without
fetching it at build time.

Auto-committed-on: dragonfly
Update the vendored tinybox and tinybus submodules to their latest
commits.

Auto-committed-on: dragonfly
Update the vendored tinycomputer submodule to the latest commit.

Auto-committed-on: dragonfly
Background delivery now drains queued messages during an active run instead of waiting for the session to go idle, and the busy guard coordinates with the drain so deliveries are not dropped or duplicated. This keeps relay and web chat replies flowing while the agent is still working.

Auto-committed-on: dragonfly
Refresh the vendored tinyhumans-sdk, tinymcp, tinymemory, and tinysearch
dependencies and adjust the tenant runtime to match their updated APIs.

Auto-committed-on: dragonfly
The background completion handler now drains and forwards every queued
result instead of stopping after the first one, so completions that
arrive in a burst are no longer silently lost.

Auto-committed-on: dragonfly
Thread purge and CRUD operations now check the busy guard before
proceeding, and web chat channel and start-chat flows respect the same
guard. This prevents deleting or mutating threads while an agent is
still running against them.

Auto-committed-on: dragonfly
Background subagent completions are now routed back to the parent
orchestrator so their results are surfaced instead of being dropped. The
registry tracks running subagents to support this delivery.

Auto-committed-on: dragonfly
Reworked the host profile lookup to reduce branching and make the
resolution path easier to follow. Behaviour is unchanged.

Auto-committed-on: dragonfly
Split the runtime bootstrap logic into smaller helper functions to make the
startup sequence easier to follow and test. Behaviour is unchanged.

Auto-committed-on: dragonfly
Moved the relay channel operations out of the provider file into their own
ops module so the provider stays focused on wiring and the request handling
logic is easier to find and test. No behaviour change.

Auto-committed-on: dragonfly
Scheduled runs now route their completion output back to the session that
created them instead of a generic delivery target, so replies land in the
conversation the user actually started. Delivery ownership is tracked per
run to keep concurrent schedules from clobbering each other's output.

Auto-committed-on: dragonfly
Transcript persistence now lives in the session store instead of the runtime
session, so the store owns all session data and the runtime session no longer
reaches into storage directly.

Auto-committed-on: dragonfly
…on is empty, and the stat is

Could you paste the diff (or at least the stat and the changed hunks)? Once I have it I'll produce the Conventional Commits message in the exact format you specified.

Auto-committed-on: dragonfly
…on is empty, and the stat is

Could you paste the diff (or at least the stat and the relevant hunks) for `crates/openhuman-core/src/agent/session_import/live.rs`? Once I can see the `+`/`-` lines I'll produce the Conventional Commits message.

Auto-committed-on: dragonfly
Introduce a bus that lets security device components publish and
subscribe to events, giving the devices module a shared channel for
coordinating state changes.

Auto-committed-on: dragonfly
…ery tests

Updated the background completion and delivery test suites to pass an explicit dispatch context into the functions under test, matching the new signatures. This keeps the tests compiling against the context-aware API without changing the behaviour they assert.

Auto-committed-on: dragonfly
Add tests exercising tenant-scoped runtime behaviour to lock in the
isolation guarantees between tenants.

Auto-committed-on: dragonfly
The turn gate was left held when a relay task errored out, blocking
subsequent turns for the profile. The gate is now released on the failure
path so later turns can proceed.

Auto-committed-on: dragonfly
The policy failure tests now reference the dispatch context through the
openhuman_core crate path and the affected calls have been reformatted to
satisfy rustfmt. No test behaviour changed.

Auto-committed-on: dragonfly
…profile

Background completion, delivery, and running-subagent bookkeeping now resolve
threads, sessions, and delivery slots through the caller's profile so one
user's Stop, delete, or busy turn can no longer gate or reach another user's
identically named thread. Tests were updated to exercise the per-profile
scoping.

Auto-committed-on: dragonfly
The background completion, delivery, and running subagent tests now obtain
their dispatch context from a local cx() helper instead of calling
DispatchCtx::ambient() at each site. This keeps the tests dispatching under
the calling task's own context while removing the repeated boilerplate.

Auto-committed-on: dragonfly
Moved the thread and session lookup helpers out of background_completions
into a dedicated thread_index module so the parent file stays focused on
completion recording and delivery. Behaviour is unchanged.

Auto-committed-on: dragonfly
Moved the per-thread delivery slot and its in-flight tracking into a dedicated slot module so the background delivery file stays focused on orchestration. Behaviour is unchanged.

Auto-committed-on: dragonfly
Removed an unused DispatchCtx import and reflowed the tool_policy field
type and a filter closure to satisfy rustfmt. No behaviour changes.

Auto-committed-on: dragonfly
Split the runtime session logic into smaller helper functions to make the
session host easier to follow and test. Behaviour is unchanged.

Auto-committed-on: dragonfly
Split the runtime session logic into smaller helper functions to make the
session host easier to follow and test. Behaviour is unchanged.

Auto-committed-on: dragonfly
Adds a tool that spawns a subagent asynchronously and returns immediately
so the parent agent can continue working while the child runs. This lets
orchestration fan out work without blocking on each subagent's completion.

Auto-committed-on: dragonfly
Adds a release-mode test suite for background completions alongside the
existing tests, covering the same behaviour under optimised builds so
regressions that only surface with release settings are caught.

Auto-committed-on: dragonfly
The cancellation-related sub-agent tests were extracted from the shared
running_subagents test file into a dedicated cancel_tests module, wired in via
a path attribute. This keeps the growing test suite organised without changing
any test behaviour.

Auto-committed-on: dragonfly
…ry slot key

Move the late-cancel doc comment onto the test that actually exercises it and
add a pending_ids helper for release tests. The delivery slot key becomes
pub(super) so sibling modules can read it.

Auto-committed-on: dragonfly
Reformatted the workspace re-export list and collapsed multi-line assert! calls in the workspace tests onto single lines. No behaviour change.

Auto-committed-on: dragonfly
…tions and subagents

Adds coverage asserting that background completions and running subagents stay scoped to their owning tenant, so cross-tenant leakage in orchestration state is caught by tests.

Auto-committed-on: dragonfly
…spatch

Move the check that alice cannot cancel bob's worker ahead of the
concurrent dispatch section so the isolation guarantee is verified on the
initial state, and replace the trailing assertion with one confirming
alice's own worker is gone after cancellation.

Auto-committed-on: dragonfly
The tenant subagent tests now build their dispatch context with
DispatchCtx::ambient() instead of process_default(), matching the
context the controller actually runs under.

Auto-committed-on: dragonfly
…tions and delivery

Adds coverage for background completion and delivery paths to verify that
tenant scoping is enforced. These tests guard against cross-tenant leakage
when background work is dispatched.

Auto-committed-on: dragonfly
Replace fully qualified `crate::core::runtime::DispatchCtx` paths with the
already imported `DispatchCtx` alias and collapse the resulting multi-line
calls, keeping the tenant isolation assertions unchanged.

Auto-committed-on: dragonfly
Add tests asserting that busy marks and cron completion ownership are keyed
by the explicit dispatch context rather than any ambient task scope, so one
profile's in-flight turn or Stop cannot affect another's thread and a job's
owner is resolved from the explicit session agent alone.

Auto-committed-on: dragonfly
Device RPC handlers now validate that the request id is present and
non-empty before dispatching, returning an error instead of proceeding
with an unusable identifier.

Auto-committed-on: dragonfly
Reordered use statements so local module imports follow the public re-exports, and reformatted an over-long function signature in the delivery slot to satisfy rustfmt. No behaviour changes.

Auto-committed-on: dragonfly
The in-flight delivery registry now lives in the parent background_delivery
module instead of the slot submodule, so it can be shared by other delivery
code paths. Behaviour is unchanged.

Auto-committed-on: dragonfly
…wners

Background delivery now records which slot and completion owner each
deferred result belongs to, so results are routed back to the right
caller instead of being matched by position. The busy guard and profile
surface were adjusted to consult the new ownership data when deciding
whether a session can accept more work.

Auto-committed-on: dragonfly
The `delivering` helper from the slot module was imported under `cfg(test)` but is no longer referenced, so the import was dropped to keep the module free of dead code.

Auto-committed-on: dragonfly
# Conflicts:
#	crates/openhuman-core/src/agent/session_store/mod.rs
#	crates/openhuman-core/src/agent/session_store/mod_tests.rs
#	crates/openhuman-core/src/agent/subagent_host/ops/graph/dispatch.rs
#	crates/openhuman-core/src/agent/subagent_host/ops/graph/transcript.rs
#	crates/openhuman-core/src/agent/subagent_host/ops/graph_tests.rs
#	crates/openhuman-core/src/cron/scheduler/origin_delivery.rs
#	crates/openhuman-core/src/cron/scheduler/origin_delivery_tests.rs
@senamakel
senamakel merged commit a8e761e into tinyhumansai:main Oct 15, 2026
7 checks passed
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-15T10:48:07.586449Z 24461b1 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@tinysweeper

tinysweeper Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

Tiny Sweeper review

⚠️ Review failed for 24461b1fe5b4. the review of #7862 did not finish within 900s

@coderabbitai

coderabbitai Bot commented Oct 15, 2026

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Note

Currently processing new changes in this PR. This may take a few minutes, please wait...

⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: a224af89-aa21-457a-bdb9-e6d7db576f92
📥 Commits

Reviewing files that changed from the base of the PR and between 02152f1 and 24461b1.

📒 Files selected for processing: 77
  • crates/openhuman-core/src/agent/orchestration/background_completions.rs
  • crates/openhuman-core/src/agent/orchestration/background_completions/thread_index.rs
  • crates/openhuman-core/src/agent/orchestration/background_completions_release_tests.rs
  • crates/openhuman-core/src/agent/orchestration/background_completions_tenant_tests.rs
  • crates/openhuman-core/src/agent/orchestration/background_completions_tests.rs
  • crates/openhuman-core/src/agent/orchestration/background_delivery.rs
  • crates/openhuman-core/src/agent/orchestration/background_delivery/slot.rs
  • crates/openhuman-core/src/agent/orchestration/background_delivery_recovery_tests.rs
  • crates/openhuman-core/src/agent/orchestration/background_delivery_slots_tests.rs
  • crates/openhuman-core/src/agent/orchestration/background_delivery_tenant_tests.rs
  • crates/openhuman-core/src/agent/orchestration/background_delivery_tests.rs
  • crates/openhuman-core/src/agent/orchestration/busy_guard.rs
  • crates/openhuman-core/src/agent/orchestration/completion_owners.rs
  • crates/openhuman-core/src/agent/orchestration/completion_target.rs
  • crates/openhuman-core/src/agent/orchestration/delivery_drain.rs
  • crates/openhuman-core/src/agent/orchestration/delivery_drain_tests.rs
  • crates/openhuman-core/src/agent/orchestration/running_subagents/cancel.rs
  • crates/openhuman-core/src/agent/orchestration/running_subagents/registry.rs
  • crates/openhuman-core/src/agent/orchestration/running_subagents/resolve.rs
  • crates/openhuman-core/src/agent/orchestration/running_subagents/roster.rs
  • crates/openhuman-core/src/agent/orchestration/running_subagents/steering.rs
  • crates/openhuman-core/src/agent/orchestration/running_subagents/wait.rs
  • crates/openhuman-core/src/agent/orchestration/running_subagents_cancel_tests.rs
  • crates/openhuman-core/src/agent/orchestration/running_subagents_steering_tests.rs
  • crates/openhuman-core/src/agent/orchestration/running_subagents_tenant_tests.rs
  • crates/openhuman-core/src/agent/orchestration/running_subagents_tests.rs
  • crates/openhuman-core/src/agent/orchestration/running_subagents_wire_tests.rs
  • crates/openhuman-core/src/agent/orchestration/subagent_control.rs
  • crates/openhuman-core/src/agent/orchestration/subagent_control_tests.rs
  • crates/openhuman-core/src/agent/orchestration/tools/close_subagent.rs
  • crates/openhuman-core/src/agent/orchestration/tools/spawn_async_subagent_execute.rs
  • crates/openhuman-core/src/agent/orchestration/tools/spawn_async_subagent_tests.rs
  • crates/openhuman-core/src/agent/orchestration/tools/steer_subagent.rs
  • crates/openhuman-core/src/agent/orchestration/tools/wait_subagent.rs
  • crates/openhuman-core/src/agent/session_host/runtime/run_loop.rs
  • crates/openhuman-core/src/agent/session_host/runtime_session.rs
  • crates/openhuman-core/src/agent/session_host/runtime_session/transcript.rs
  • crates/openhuman-core/src/agent/session_import/live.rs
  • crates/openhuman-core/src/agent/session_store/mod.rs
  • crates/openhuman-core/src/agent/session_store/mod_tests.rs
  • crates/openhuman-core/src/channels/providers/relay/ops.rs
  • crates/openhuman-core/src/channels/providers/relay/ops_tests.rs
  • crates/openhuman-core/src/core/runtime/bootstrap.rs
  • crates/openhuman-core/src/core/runtime/tenant.rs
  • crates/openhuman-core/src/core/runtime/tenant_tests.rs
  • crates/openhuman-core/src/cron/completion_owner.rs
  • crates/openhuman-core/src/cron/completion_owner_tests.rs
  • crates/openhuman-core/src/cron/limits_tests.rs
  • crates/openhuman-core/src/cron/ops.rs
  • crates/openhuman-core/src/cron/ops_tests.rs
  • crates/openhuman-core/src/cron/scheduler/delivery.rs
  • crates/openhuman-core/src/cron/scheduler/host.rs
  • crates/openhuman-core/src/cron/scheduler/origin_delivery.rs
  • crates/openhuman-core/src/cron/scheduler/origin_delivery_tests.rs
  • crates/openhuman-core/src/cron/scheduler/run_delivery.rs
  • crates/openhuman-core/src/cron/scheduler_classifier_and_delivery_tests.rs
  • crates/openhuman-core/src/cron/scheduler_frequency_tests.rs
  • crates/openhuman-core/src/cron/scheduler_halt_and_persist_tests.rs
  • crates/openhuman-core/src/cron/schemas.rs
  • crates/openhuman-core/src/desktop/notifications/bus_tests_2_tests.rs
  • crates/openhuman-core/src/profiles/host.rs
  • crates/openhuman-core/src/profiles/surface.rs
  • crates/openhuman-core/src/profiles/turn_gate.rs
  • crates/openhuman-core/src/profiles/turn_gate_tests.rs
  • crates/openhuman-core/src/security/devices/bus.rs
  • crates/openhuman-core/src/security/devices/rpc.rs
  • crates/openhuman-core/src/security/devices/schemas.rs
  • crates/openhuman-core/src/threads/ops/crud.rs
  • crates/openhuman-core/src/threads/ops/purge.rs
  • crates/openhuman-core/src/threads/ops_conversion_tests.rs
  • crates/openhuman-core/src/web_chat/ops/channel_ops.rs
  • crates/openhuman-core/src/web_chat/ops/start_chat.rs
  • crates/openhuman-core/src/web_chat/run_task.rs
  • crates/openhuman-core/src/web_chat/web_tests_session_and_concurrency_tests.rs
  • crates/openhuman-embed/src/cron.rs
  • crates/openhuman-embed/src/runtime/mod.rs
  • tests/support/cron_policy_failure.rs
+-----------------------------------------------+
| Caches are bugs waiting to happen. - Rob Pike |
+-----------------------------------------------+
  \
   \   (\__/)
       (•ㅅ•)
       /   づ
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant