fix(orchestration): run device sub-agents from master chat; serialize master-ask seq#4778
Conversation
…error handling and context management
|
Warning Review limit reachedYou’ve reached a temporary PR review limit under our Fair Usage Limits Policy. Next review available in: 12 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughThe orchestration flow adds centralized local subagent execution and result mapping, while the local Master-message path now atomically persists sequence allocation, session updates, and message insertion. ChangesLocal orchestration updates
Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
participant Forwarder as run_local_agent_and_forward
participant Helper as run_local_subagent
participant Registry as AgentDefinitionRegistry
participant Runner as run_subagent
Forwarder->>Helper: Pass prompt and context
Helper->>Registry: Resolve agent_id
Helper->>Runner: Execute with root parent context
Runner-->>Helper: Return SubagentRunStatus
Helper-->>Forwarder: Return success flag and output
Possibly related PRs
Suggested labels: Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
Comment |
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/openhuman/orchestration/effect_executor.rs (1)
288-309: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick winWrap the completion persist in
in_immediate_txn—next_session_seq+insert_messagehere still run in autocommit, so the same(agent_id, session_id)can read the sameMAX(seq)and write a duplicate ordinal. This path should mirror the master-ask writer and allocate + insert under one immediate transaction to avoid a dropped wake-up.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/openhuman/orchestration/effect_executor.rs` around lines 288 - 309, The completion persistence in the tool-completion path is not atomic, allowing duplicate session sequence values; update the block in the effect executor using the existing in_immediate_txn helper, wrapping both next_session_seq and insert_message in the same immediate transaction, while preserving the existing error context and returned sequence.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@src/openhuman/orchestration/effect_executor.rs`:
- Around line 288-309: The completion persistence in the tool-completion path is
not atomic, allowing duplicate session sequence values; update the block in the
effect executor using the existing in_immediate_txn helper, wrapping both
next_session_seq and insert_message in the same immediate transaction, while
preserving the existing error context and returned sequence.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 946a141d-8554-4e31-88af-1447ed886e0f
📒 Files selected for processing (2)
src/openhuman/orchestration/effect_executor.rssrc/openhuman/orchestration/schemas.rs
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3c430d2473
ℹ️ About Codex in GitHub
Codex has been enabled to automatically 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".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
sanil-23
left a comment
There was a problem hiding this comment.
Approving — the core logic is correct and verified:
- Seq serialization faithfully mirrors the
ingest.rswith_connection(|c| in_immediate_txn(c, ...))pattern on the same(local, "master")key, so it genuinely closes the concurrentMAX(seq)read-modify-write race (the duplicate-seq → backend idempotency-dedupe-without-waking failure). Inner logic is unchanged; only serialized. run_local_subagentinstalls a background root parent viawith_root_parentand dispatches throughrun_subagent— the right fix for the turn-lessNoParentContextspawn rejection. Every failure maps to(false, msg)so the brain always gets atool_completion.- Security preserved: local execution stays gated to Master-chat origin in
dispatch_device_tool(is_local_execution_tool && !cycle_is_master → deny non_master_origin); this PR doesn't touch that gate. A2A cycles still can't induce local execution.
Non-blocking follow-ups (please address in this PR or a fast follow):
- Tests / checklist accuracy. The checklist marks
Tests added (happy/unknown-agent/provider-error)andDiff coverage ≥ 80%as done, but the body notes both are "pending" and no test code is in the diff. Coverage CI passed on the combined ratio (reindented + existing integration coverage), but the new failure branches — unknown-agent-id, provider/parent-build error, andAwaitingUser/Incomplete— are the ones worth the claimed unit tests. Please land them or correct the checkboxes. - codex P2 (toolkit options):
SubagentRunOptions { context, ..Default::default() }forwards onlycontext— any toolkit/integration options intended for the local run are defaulted away. Resolve or explicitly defer on the thread. AwaitingUsersemantics (minor): a clarification question yields(false, …), so the forwarded body reads… failedfor a legitimate needs-input state. The question is surfaced, but consider a distinct marker so the brain re-prompts vs. treats it as an error.- Invariant hole (minor): a
Config::load_or_init()failure returnsErrand forwards notool_completion, unlike every other failure path which sends(false, msg). Pre-existing behavior, but it leaves the "brain always learns the outcome" invariant with one gap.
Nice work — this is the client half of the master-chat wake round-trip and the seq fix directly closes a silent-drop class we hit on the backend side.
… enforce scoping requirements This update introduces a new parameter for the , ensuring that requests are properly scoped to a specific Composio toolkit. If the is not provided, the request will be rejected, enhancing security and preventing unscoped access. Additionally, tests have been added to verify this behavior.
Summary
tools_agent,code_executor,researcher) requested bythe hosted brain now actually run from a Master-chat cycle instead of failing.
seqinside an IMMEDIATEtransaction, matching the DM path, so concurrent sends can't drop a wake.
Problem
spawn_async_subagentfrom a bare background task with noagent-turn on the stack, so
current_parent()wasNoneand the spawn was rejectedwith
spawn_async_subagent called outside of an agent turn— every "check my skills"/ "summarize my mails" request failed.
MAX(seq)+1then inserted outside a transaction,unlike the DM ingest writer on the same
(local, "master")key. Two concurrentmaster sends could read the same max and emit a duplicate
seq, which the backendidempotency-dedupes without waking.
Solution
run_local_subagentineffect_executor: installs a background rootParentExecutionContextviawith_root_parent(provider/tools/memory/workspace froma config-built agent) and dispatches through
run_subagentdirectly — the same pathdelegation / workflow / team surfaces use.
run_subagentis synchronous (returns thereal output, not an async ref) and skips the tool-only allowlist gate. Any failure
becomes a
(false, msg)completion so the brain always gets atool_completion. Theexec-gate (Master-chat-only) and the async forward contract are unchanged.
next_session_seq→insert instore::in_immediate_txn,mirroring
ingest.rs.Submission Checklist
run_local_subagent(happy / unknown-agent / provider-error) and master-ask seq txn pending
pnpm test:ruston the new linesN/A: orchestration device-exec is behaviour-fix## Related— N/AN/A: not a release-cut surfaceCloses #NNNin## RelatedImpact
Master-chat cycles; no change to A2A cycles (still gated by exec_gate).
integrations fetch) — a real provider/inference cost per invocation, by design.
wire fields; A2A denial path unchanged.
Summary by CodeRabbit
New Features
Bug Fixes