Skip to content

feat(core): version/shutdown/update RPCs + mid-thread integration refresh - #1195

Merged
senamakel merged 5 commits into
tinyhumansai:mainfrom
senamakel:feat/core-lifecycle-rpc-and-live-integrations
May 5, 2026
Merged

senamakel merged 5 commits into
tinyhumansai:mainfrom
senamakel:feat/core-lifecycle-rpc-and-live-integrations

Conversation

@senamakel

@senamakel senamakel commented May 4, 2026 •

Copy link
Copy Markdown
Member

Summary

  • New JSON-RPC controllers on the core: update.version, update.run, service.shutdown so the desktop frontend can ask the running core what version it is, trigger a one-call check → stage → restart, or gracefully exit it. service.restart already existed.
  • composio_list_tools now emits compact markdown instead of pasting full JSON tool schemas, and defaults to filtering out toolkits the user hasn't connected (escape hatch: include_unconnected=true). Both are major token wins on the agent loop.
  • Sub-agent spawn pre-flight (spawn_subagent integrations gate + subagent_runner::run_typed_mode) now refreshes connected integrations from the global cache at spawn time, so a toolkit the user authorises mid-thread (e.g. Calendly) is visible without restarting the app or opening a new thread.

Problem

Two related rough edges + one capability gap:

  1. Frontend update orchestration. The core has had update.check and update.apply for a while, but no single "do the update" command and no cheap way to read the current binary's version without paying a GitHub round-trip. Nothing for graceful shutdown either, even though restart was wired.
  2. composio_list_tools is hugely expensive. It returns the full OpenAI function-calling schema for every tool the backend exposes — the parameter schemas dominate the response and burn a lot of tokens in the agent loop. It also returned actions for every allowlisted toolkit, including ones the user hadn't connected.
  3. Mid-thread Calendly authorisation didn't work. The parent session's connected_integrations Vec is intentionally frozen on the first turn (so the system-prompt KV-cache prefix stays stable). That meant a toolkit the user OAuth'd mid-thread was missing from parent.connected_integrations, the spawn_subagent(integrations_agent, toolkit="calendly", …) pre-flight rejected it as "not in the allowlist", and the user had to start a new thread or restart the app to use it.

Solution

RPCs

  • update.version — returns { version, target_triple, asset_prefix } from CARGO_PKG_VERSION + the existing platform_triple() helper. No network. Cheap discovery.
  • update.run — orchestrates check → stage → restart in one call. Re-uses the existing validate_download_url / validate_asset_name safety net so the orchestrator can't bypass the gates update.apply already enforces. Returns UpdateRunResult { applied, staged_path, restart_requested, message, … }.
  • service.shutdown — mirrors service.restart: publishes a new SystemShutdownRequested event variant, consumed by a ShutdownSubscriber that calls process::exit(0) after a 150 ms flush window. Subscriber wired in core/jsonrpc.rs::register_domain_subscribers next to the existing restart one.

composio_list_tools markdown + connected-only

  • New render_tools_markdown groups tools by toolkit (parsed from slug prefix), shows \`SLUG\` — description **req:** a, b **opt:** c, d per tool, drops the full JSON parameter schemas. Wired through execute_with_options + supports_markdown=true so the harness picks it up only when prefer_markdown is set; raw JSON is still the primary output() for direct CLI/RPC callers.
  • New include_unconnected: bool parameter (default false). When false the tool calls list_connections() after fetching tools and drops any tool whose toolkit isn't in the user's ACTIVE/CONNECTED set. Mirrors the same status allowlist composio_list_connections uses. Surfacing an error (instead of silently returning []) if the connections fetch fails so the agent can retry with include_unconnected=true.

Mid-thread integration refresh

  • The composio side already invalidates the global INTEGRATIONS_CACHE once OAuth reaches ACTIVE (via ComposioConnectionCreatedSubscriber). The miss was purely the parent session's stale in-memory Vec.
  • In spawn_subagent.rs's integrations_agent toolkit gate AND in subagent_runner::run_typed_mode, fetch the live list via composio::fetch_connected_integrations(&config) instead of reading parent.connected_integrations. That call is a cache hit on the warm path; the cache invalidation makes it a fresh fetch immediately after a new authorisation. Falls back to the parent's frozen list when the fetch returns empty (offline / not signed in) so existing behaviour is preserved.
  • The parent's own system prompt is untouched — KV-cache prefix is unaffected; only the spawn pre-flight and the freshly-built child prompt benefit.

Submission Checklist

  • Tests added or updated (happy path + at least one failure / edge case) per docs/TESTING-STRATEGY.md
  • N/A: changed-line coverage delta is small (Rust-only, in domains already covered by existing service/update/composio test suites). Will run pnpm test:rust + pnpm test:coverage locally and address if diff-cover flags anything below 80%.
  • N/A: behaviour-only change — no new user-facing capability rows for the matrix
  • N/A: no linked issue
  • No new external network dependencies introduced (mock backend used per docs/TESTING-STRATEGY.md)
  • N/A: doesn't touch a release-cut surface listed in RELEASE-MANUAL-SMOKE.md
  • N/A: no linked issue

Impact

  • Desktop runtime. Exposes three new RPC methods; the frontend can now wire a "check for updates" / "restart" / "shutdown" surface without going through CLI or the manual update.apply + service.restart two-step.
  • Agent token usage. composio_list_tools markdown output materially shortens responses — expected ~50–80% smaller depending on toolkit. The connected-only default avoids surfacing actions the user can't actually call.
  • Mid-thread UX. OAuthing a new integration during a live chat now "just works" without forcing the user to start a new thread.
  • Compatibility. Additive only; no existing RPC / event variant / tool signature changed in a way that breaks callers.

Related

  • Closes:
  • Follow-up PR(s)/TODOs:

Summary by CodeRabbit

  • New Features

    • Process-wide graceful shutdown request and a service shutdown command
    • Markdown-formatted tool listings with optional connection-scoped filtering
    • Update orchestration (check → download/stage → request restart) plus version-info endpoint
    • Sub-agent spawning now refreshes live integrations at spawn time
  • Bug Fixes

    • Integration checks use refreshed live data instead of frozen session lists
    • Updated guidance: "Connections → Integrations" for retrying integration actions

senamakel added 3 commits May 4, 2026 14:53
…erface

- Added `service_shutdown` function to handle shutdown requests and publish events.
- Introduced `ShutdownSubscriber` to manage the shutdown process with a grace period.
- Updated schemas and controllers to include shutdown functionality.
- Enhanced event handling for shutdown requests, ensuring proper logging and state management.
- Added tests for shutdown functionality to ensure reliability and correctness.
The parent session's `connected_integrations` Vec is frozen on the very
first turn (so the system-prompt KV-cache prefix stays stable), which
means a toolkit the user authorises mid-thread (e.g. Calendly) was
invisible to the spawn pre-flight and rejected as "not allowlisted",
forcing the user to open a new thread or restart the app.

Re-fetch the list at spawn time via `composio::fetch_connected_integrations`
in two places — `spawn_subagent`'s `integrations_agent` allowlist gate
and `subagent_runner::run_typed_mode`'s toolkit lookup + child prompt
narrowing. The global cache is invalidated by
`ComposioConnectionCreatedSubscriber` once OAuth reaches ACTIVE, so
this is a cheap warm-path call and falls back to the parent's frozen
list when the live fetch returns empty (offline / not signed in).

The parent's own session prompt is untouched — the KV-cache prefix
stays stable; only the spawn pre-flight and the freshly-built child
prompt benefit.
Whitespace / import-ordering changes from the pre-push hook.
@senamakel
senamakel requested a review from a team May 4, 2026 22:05
@coderabbitai

coderabbitai Bot commented May 4, 2026 •

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

Adds a process-wide graceful shutdown event and subscriber, exposes a shutdown RPC, refreshes live integrations for subagent/tool gating, enhances Composio tools with markdown and connection-scoped filtering, and introduces update.version/update.run RPCs plus public platform_triple and related types/schemas.

Changes

Graceful Shutdown Flow

Layer / File(s) Summary
Domain Event
src/core/event_bus/events.rs
Adds DomainEvent::SystemShutdownRequested { source, reason } and routes it under the "system" domain.
Subscriber Registration
src/core/jsonrpc.rs, src/openhuman/service/bus.rs
Registers register_shutdown_subscriber() at bootstrap; adds SHUTDOWN_HANDLE, SHUTDOWN_IN_PROGRESS, and ShutdownSubscriber that atomically claims a one-shot gate and schedules a 150ms delayed std::process::exit(0).
Orchestration API
src/openhuman/service/shutdown.rs, src/openhuman/service/ops.rs
New service_shutdown implementation and RPC wrapper; normalizes inputs, publishes SystemShutdownRequested, and returns ShutdownStatus without exiting the process.
Schema / Wiring
src/openhuman/service/schemas.rs, src/openhuman/service/mod.rs
Adds service.shutdown schema/controller, refactors lifecycle schema generation (restart/shutdown share optional {source,reason} inputs), and re-exports ShutdownStatus.
Tests
src/openhuman/service/bus.rs, src/openhuman/service/schemas.rs
Adds shutdown subscriber tests (namespace/domain filtering, early-return, duplicate-suppression) and updates schema tests to include shutdown.

Composio Tools & Connected Integrations

Layer / File(s) Summary
Data / Allowlist Refresh
src/openhuman/agent/harness/subagent_runner/ops.rs, src/openhuman/tools/impl/agent/spawn_subagent.rs
At spawn-time, derives live_integrations via config + fetch_connected_integrations_status and uses it for toolkit allowlists; treats Authoritative(empty) as valid and falls back to parent's frozen list on Unavailable or config load failure; updates user guidance text to “Connections → Integrations”.
Fetch Status API
src/openhuman/composio/ops.rs, src/openhuman/composio/mod.rs
Introduces FetchConnectedIntegrationsStatus enum and fetch_connected_integrations_status() cached API; updates fetch_connected_integrations() to map Unavailable → empty Vec.
Rendering & Filtering Helpers
src/openhuman/composio/tools.rs
Adds retain_connected_tools, markdown helpers (one_line, split_arg_names, render_tools_markdown), execute_with_options, and supports_markdown(); honors include_unconnected and ToolCallOptions::prefer_markdown, and soft-fails on connection-fetch errors.
Tests
src/openhuman/composio/tools_tests.rs
Adds unit tests for markdown rendering (grouping, arg formatting, schema omission, length), connected-toolkit case-insensitive filtering, and empty-response handling.

Update Domain: version / run

Layer / File(s) Summary
Types
src/openhuman/update/types.rs
Adds VersionInfo and UpdateRunResult serializable types for update.version and update.run.
RPC Implementation
src/openhuman/update/ops.rs, src/openhuman/update/core.rs
Adds update_version() and update_run() RPCs; update_run implements check → validate → download_and_stage → request restart orchestration; makes platform_triple() public.
Schemas & Controllers
src/openhuman/update/schemas.rs
Registers new version and run schemas and controller handlers (handle_version, handle_run); tests updated to expect 4 schemas.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant RPC_Handler
    participant Event_Bus
    participant Shutdown_Subscriber
    participant Process

    Client->>RPC_Handler: service_shutdown(source, reason)
    activate RPC_Handler
    RPC_Handler->>RPC_Handler: normalize source/reason
    RPC_Handler->>Event_Bus: init bus
    RPC_Handler->>Event_Bus: publish SystemShutdownRequested
    Event_Bus->>Shutdown_Subscriber: deliver event
    activate Shutdown_Subscriber
    Shutdown_Subscriber->>Shutdown_Subscriber: compare-and-set SHUTDOWN_IN_PROGRESS
    Shutdown_Subscriber->>Shutdown_Subscriber: schedule 150ms delay
    RPC_Handler->>Client: return ShutdownStatus{accepted:true}
    deactivate RPC_Handler
    Shutdown_Subscriber->>Process: exit(0) after delay
    deactivate Shutdown_Subscriber
Loading
sequenceDiagram
    participant Client
    participant RPC_Handler
    participant Update_Service
    participant Asset_Validator
    participant Downloader
    participant Restart_Service

    Client->>RPC_Handler: update_run()
    activate RPC_Handler
    RPC_Handler->>Update_Service: check_available()
    alt no update
        RPC_Handler->>Client: return UpdateRunResult{update_available:false}
    else update found
        RPC_Handler->>Asset_Validator: validate URL & asset name
        alt invalid
            RPC_Handler->>Client: return error (invalid/missing asset)
        else valid
            RPC_Handler->>Downloader: download_and_stage()
            alt download fails
                RPC_Handler->>Client: return error (download/stage failed)
            else download success
                RPC_Handler->>Restart_Service: service_restart()
                RPC_Handler->>Client: return UpdateRunResult{applied:true,restart_requested:...}
            end
        end
    end
    deactivate RPC_Handler
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • tinyhumansai/openhuman#501: Modifies Composio integration, event-bus subscriber registration, and JSON-RPC subscriber bootstrap — overlaps with composio and subscriber changes.
  • tinyhumansai/openhuman#372: Related update subsystem changes (update controllers/ops/types and platform triple visibility).
  • tinyhumansai/openhuman#520: Related to connected-integrations flow and live connected-integrations fetching/usage.

Poem

🐰
I nibble logs and tidy threads,
I whisper "shutdown" to sleepy heads.
Tools in markdown, assets aligned,
Live integrations freshly signed.
A gentle hop — the system's kind.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title accurately summarizes the main changes: three new RPCs (version, shutdown, update) and mid-thread integration refresh via live fetching.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
src/openhuman/update/ops.rs (1)

69-73: 💤 Low value

Silent loss of error context when serialization fails.

If serde_json::to_value(&result) fails, returning Value::Null discards both the original UpdateRunResult and the serialization error. The same pattern appears at lines 93, 130, and 175. Consider logging or embedding the error like the fallback in update_version (line 27).

♻️ Proposed fix
-            serde_json::to_value(&result).unwrap_or(Value::Null),
+            serde_json::to_value(&result).unwrap_or_else(|e| {
+                log::warn!("[update:rpc] serialization failed: {e}");
+                serde_json::json!({ "error": format!("serialization failed: {e}") })
+            }),
🤖 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/update/ops.rs` around lines 69 - 73, The current use of
serde_json::to_value(&result).unwrap_or(Value::Null) in the
RpcOutcome::single_log call (and the other occurrences at the same pattern)
silently drops serialization errors and returns Value::Null; change these to
capture the serde_json::to_value error and include it in the RpcOutcome/logging
(similar to the fallback used in update_version) so the returned payload
contains either the serialized UpdateRunResult or an object/string describing
the serialization failure and error details; update the code paths that call
RpcOutcome::single_log (where serde_json::to_value is used) to log or embed the
error instead of unwrapping to Value::Null.
🤖 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.

Inline comments:
In `@src/openhuman/agent/harness/subagent_runner/ops.rs`:
- Around line 179-203: The code currently treats an Ok([]) from
fetch_connected_integrations(&config).await as a failure and falls back to
parent.connected_integrations; change the logic in the block using
Config::load_or_init and fetch_connected_integrations so that only Err(e)
triggers the fallback to parent.connected_integrations, while an Ok(fresh) —
even if fresh.is_empty() — is used as the authoritative list (adjust
tracing/debug messages accordingly to log an empty but successful refresh).
Apply the same change in the other location (the spawn_subagent logic in
spawn_subagent.rs) so both paths use fresh on Ok and only use
parent.connected_integrations on Err.

In `@src/openhuman/composio/tools.rs`:
- Around line 466-472: The docstring currently claims the endpoint returns a
top-level JSON array of OpenAI function schemas but the implementation
serializes ComposioToolsResponse (an object with a tools array), causing callers
to look in the wrong place; update the documentation string near the
ComposioToolsResponse usage to state the actual response shape is a JSON object
with a "tools" array and that each entry contains the function schema (so
callers should read tools[*].function.name for the slug to pass as the `tool`
argument to composio_execute).

---

Nitpick comments:
In `@src/openhuman/update/ops.rs`:
- Around line 69-73: The current use of
serde_json::to_value(&result).unwrap_or(Value::Null) in the
RpcOutcome::single_log call (and the other occurrences at the same pattern)
silently drops serialization errors and returns Value::Null; change these to
capture the serde_json::to_value error and include it in the RpcOutcome/logging
(similar to the fallback used in update_version) so the returned payload
contains either the serialized UpdateRunResult or an object/string describing
the serialization failure and error details; update the code paths that call
RpcOutcome::single_log (where serde_json::to_value is used) to log or embed the
error instead of unwrapping to Value::Null.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 9ce52267-1fb2-4a18-9d0a-1f5ddc4bc3f5

📥 Commits

Reviewing files that changed from the base of the PR and between 229e374 and d71f8a0.

⛔ Files ignored due to path filters (1)
  • app/src-tauri/Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (15)
  • src/core/event_bus/events.rs
  • src/core/jsonrpc.rs
  • src/openhuman/agent/harness/subagent_runner/ops.rs
  • src/openhuman/composio/tools.rs
  • src/openhuman/composio/tools_tests.rs
  • src/openhuman/service/bus.rs
  • src/openhuman/service/mod.rs
  • src/openhuman/service/ops.rs
  • src/openhuman/service/schemas.rs
  • src/openhuman/service/shutdown.rs
  • src/openhuman/tools/impl/agent/spawn_subagent.rs
  • src/openhuman/update/core.rs
  • src/openhuman/update/ops.rs
  • src/openhuman/update/schemas.rs
  • src/openhuman/update/types.rs

Comment thread src/openhuman/agent/harness/subagent_runner/ops.rs
Comment thread src/openhuman/composio/tools.rs Outdated
CodeRabbit caught that `Ok([])` from `fetch_connected_integrations` is a
valid "no active integrations" state, but the spawn-time refresh treated
it as a fetch failure and fell back to the parent's frozen list. That
silently re-introduced toolkits the user had just disconnected mid-
thread.

Both call sites (`subagent_runner::run_typed_mode` and
`spawn_subagent`'s `integrations_agent` allowlist gate) now adopt
whatever `fetch_connected_integrations` returns — empty or not — as
truth, and only fall back to `parent.connected_integrations` when the
config load itself errors.

Also clarify `composio_list_tools`'s description: the result is a JSON
object with a `tools` array, not a top-level array.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 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.

Inline comments:
In `@src/openhuman/tools/impl/agent/spawn_subagent.rs`:
- Around line 234-279: The fetch_connected_integrations call is ambiguous
because an empty Vec can mean either "authoritative empty" or
"transient/unavailable", so change the composio API to return an enum (e.g.
FetchConnectedIntegrationsStatus::Authoritative(Vec<ConnectedIntegration>) |
::Unavailable) and update the caller in spawn_subagent.rs: call the new
fetch_connected_integrations, match on Authoritative(vec) to use that result
(including empty vec), and treat Unavailable by falling back to
parent_ctx.as_ref().map(|p|
p.connected_integrations.clone()).unwrap_or_default(); keep Config::load_or_init
error handling as-is but only treat an empty authoritative Vec as truth and
Unavailable as non-authoritative fallback that preserves prior behaviour
(affecting live_integrations and allowlist).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 478507bb-2530-4f6f-8cfe-8f4fb184f899

📥 Commits

Reviewing files that changed from the base of the PR and between d71f8a0 and 37606d8.

📒 Files selected for processing (3)
  • src/openhuman/agent/harness/subagent_runner/ops.rs
  • src/openhuman/composio/tools.rs
  • src/openhuman/tools/impl/agent/spawn_subagent.rs
✅ Files skipped from review due to trivial changes (1)
  • src/openhuman/composio/tools.rs
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/openhuman/agent/harness/subagent_runner/ops.rs

Comment thread src/openhuman/tools/impl/agent/spawn_subagent.rs
CodeRabbit follow-up: the previous fix made the spawn pre-flight trust
an empty Vec from `fetch_connected_integrations` as truth, but that
function also returns empty when the backend is unavailable (no
client / transient 5xx during list_toolkits / list_connections).
Treating "unavailable" as "user has no integrations" would silently
reject every toolkit during a transient outage.

Add `FetchConnectedIntegrationsStatus { Authoritative(Vec) | Unavailable }`
and a sibling `fetch_connected_integrations_status` that exposes the
discriminator. Cache hits are by definition Authoritative because we
only ever cache the `Some(...)` arm of `_uncached`.

Both spawn-time callers (`subagent_runner::run_typed_mode` and
`spawn_subagent`'s integrations gate) now distinguish the two:

- Authoritative — adopt as truth, including the empty case (user
  disconnected their last integration mid-thread).
- Unavailable — fall back to the parent's frozen snapshot so the spawn
  pre-flight stays usable during transient backend errors.

The legacy `fetch_connected_integrations` is preserved for prompt-
building callers (`turn.rs`, `dispatch.rs`, `escalation.rs`,
`onboarding_status.rs`) where the empty/unavailable distinction
doesn't matter.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/openhuman/tools/impl/agent/spawn_subagent.rs (1)

234-242: 💤 Low value

Comment should reflect status-based fallback, not "returns empty".

The comment at lines 240-242 states the code "Falls back to the parent's frozen list when the live fetch returns empty" — but the actual logic now falls back on Unavailable, not on empty results. An authoritative empty list is correctly treated as truth (no fallback). Consider updating the comment to match the implementation.

📝 Suggested comment update
             // invalidated by `ComposioConnectionCreatedSubscriber` once
             // OAuth reaches ACTIVE — so the pre-flight sees the latest
-            // truth. Falls back to the parent's frozen list when the
-            // live fetch returns empty (no signed-in user, backend
-            // unreachable, …) so offline behaviour is unchanged.
+            // truth. Falls back to the parent's frozen list only when
+            // the backend is unavailable (no client, transient error)
+            // so offline behaviour is unchanged; an authoritative empty
+            // list from the backend is treated as truth.
🤖 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/tools/impl/agent/spawn_subagent.rs` around lines 234 - 242, The
comment describing fallback behavior in spawn_subagent.rs is inaccurate: it says
fallback occurs when the live fetch "returns empty" but the code actually falls
back when the fetch status is Unavailable (an authoritative empty Vec is
accepted as truth). Update the comment near the block that mentions
`fetch_connected_integrations` / `ComposioConnectionCreatedSubscriber` to state
that the code refreshes from the global integrations cache and only falls back
to the parent's frozen `connected_integrations` when the refresh reports
`Unavailable`; an empty list from the live fetch should be treated as
authoritative and not trigger the fallback.
🤖 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.

Nitpick comments:
In `@src/openhuman/tools/impl/agent/spawn_subagent.rs`:
- Around line 234-242: The comment describing fallback behavior in
spawn_subagent.rs is inaccurate: it says fallback occurs when the live fetch
"returns empty" but the code actually falls back when the fetch status is
Unavailable (an authoritative empty Vec is accepted as truth). Update the
comment near the block that mentions `fetch_connected_integrations` /
`ComposioConnectionCreatedSubscriber` to state that the code refreshes from the
global integrations cache and only falls back to the parent's frozen
`connected_integrations` when the refresh reports `Unavailable`; an empty list
from the live fetch should be treated as authoritative and not trigger the
fallback.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: eb65a563-29fc-43ec-b231-4a5d434d0cac

📥 Commits

Reviewing files that changed from the base of the PR and between 37606d8 and 20bb8cf.

📒 Files selected for processing (4)
  • src/openhuman/agent/harness/subagent_runner/ops.rs
  • src/openhuman/composio/mod.rs
  • src/openhuman/composio/ops.rs
  • src/openhuman/tools/impl/agent/spawn_subagent.rs
✅ Files skipped from review due to trivial changes (1)
  • src/openhuman/composio/mod.rs
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/openhuman/agent/harness/subagent_runner/ops.rs

@senamakel
senamakel merged commit 24019ed into tinyhumansai:main May 5, 2026
20 checks passed
jwalin-shah added a commit to jwalin-shah/openhuman that referenced this pull request May 5, 2026
* feat(remotion): Ghosty character library with transparent MOV variants (tinyhumansai#1059)

Co-authored-by: WOZCODE <contact@withwoz.com>

* feat(composio/gmail): sync into memory tree (Slack-parity) (tinyhumansai#1056)

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat(scheduler-gate): throttle background AI on battery / busy CPU (tinyhumansai#1062)

* fix(core,cef): run core in-process and stop orphaning CEF helpers on Cmd+Q (tinyhumansai#1061)

* ci: add dedicated staging release workflow (tinyhumansai#1066)

* fix(sentry): Rust source context + per-release deploy marker (tinyhumansai#405) (tinyhumansai#1067)

* fix(welcome): re-enable OAuth buttons with focus/timeout recovery (tinyhumansai#1049) (tinyhumansai#1069)

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(dependencies): update pnpm-lock.yaml and Cargo.lock for package… (tinyhumansai#1082)

* fix(onboarding): personalize welcome agent greeting with user identity (tinyhumansai#1078)

* fix(chat): make agent message bubbles fit content width (tinyhumansai#1083)

* Feat/dmg checks (tinyhumansai#1084)

* fix(linux): Add X11 platform flags to .deb package launcher (tinyhumansai#1087)

Co-authored-by: unn-Known1 <unn-known1@users.noreply.github.com>

* fix(sentry): auto-send React events; collapse core→tauri for desktop (tinyhumansai#1086)

Co-authored-by: Steven Enamakel <enamakel@tinyhumans.ai>

* fix(cef): run blank reload guard on the CEF UI thread (tinyhumansai#1092)

* fix(app): reload webview instead of restart_app in dev mode (tinyhumansai#1068) (tinyhumansai#1071)

* fix(linux): deliver X11 ozone flags via custom .desktop template (tinyhumansai#1091)

* fix(webview-accounts): retry data-dir purge so CEF handle race doesn't leak cookies (tinyhumansai#1076) (tinyhumansai#1081)

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Steven Enamakel <enamakel@tinyhumans.ai>

* fix(webview/slack): media perms + deep-link isolation (tinyhumansai#1074) (tinyhumansai#1080)

Co-authored-by: Steven Enamakel <enamakel@tinyhumans.ai>

* ci(release): split staging vs production workflows; promote staging tags (tinyhumansai#1094)

* Update release-staging.yml (tinyhumansai#1097)

* chore(staging): v0.53.5

* chore(staging): v0.53.6

* ci(staging): cut staging from main; add act local-debug helper (tinyhumansai#1099)

* chore(staging): v0.53.7

* fix(ci): correct sentry-cli download URL and trap scope (tinyhumansai#1100)

* chore(staging): v0.53.8

* feat(chat): forward thread_id to backend for KV cache locality (tinyhumansai#1095)

* fix(ci): bump pinned sentry-cli to 3.4.1 (2.34.2 was never published) (tinyhumansai#1102)

* chore(staging): v0.53.9

* fix(ci): drop bash trap in upload_sentry_symbols.sh; inline cleanup (tinyhumansai#1103)

* chore(staging): v0.53.10

* refactor(session): flatten session_raw/, switch md to YYYY_MM_DD (tinyhumansai#1098)

* Add full Composio managed-auth toolkit catalog (tinyhumansai#1093)

* ci: add diff-aware 80% coverage gate (Vitest + cargo-llvm-cov) (tinyhumansai#1104)

* feat(scripts): pnpm work + pnpm debug for agent-driven workflows (tinyhumansai#1105)

* ci: pull pnpm into CI image, drop redundant setup steps (tinyhumansai#1107)

* docs: add Cursor Cloud specific instructions to AGENTS.md (tinyhumansai#1106)

Co-authored-by: Cursor Agent <cursoragent@cursor.com>

* chore(staging): v0.53.11

* docs: surface 80% coverage gate and scripts/debug runners (tinyhumansai#1108)

* feat(app): show Composio integrations as sorted icon grid on Skills (tinyhumansai#1109)

Co-authored-by: Cursor Agent <cursoragent@cursor.com>

* feat(composio): client-side trigger enable/disable toggles (tinyhumansai#1110)

* feat(skills): channels grid + integrations card polish; tolerant Composio trigger decode (tinyhumansai#1112)

* chore(staging): v0.53.12

* feat(home): early-bird banner + assistant→agent terminology (tinyhumansai#1113)

* feat(updater): in-app auto-update with auto-download + restart prompt (tinyhumansai#677) (tinyhumansai#1114)

* chore(claude): add ship-and-babysit slash command (tinyhumansai#1115)

* feat(home): EarlyBirdyBanner + agent terminology + LinkedIn enrichment model pin (tinyhumansai#1118)

* fix(chat): single onboarding thread in sidebar after wizard (tinyhumansai#1116)

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Steven Enamakel <senamakel@users.noreply.github.com>

* fix: filter out global namespace from citation chips (tinyhumansai#1124)

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Co-authored-by: senamakel-droid <281415773+senamakel-droid@users.noreply.github.com>

* feat(nav): enable Memory tab in BottomTabBar (tinyhumansai#1125)

* feat(memory): singleton ingestion + status RPC + UI pill (tinyhumansai#1126)

* feat(human): mascot tab with viseme-driven lipsync (staging only) (tinyhumansai#1127)

* Fix CEF zombie processes on full app close and restart (tinyhumansai#1128)

Co-authored-by: senamakel-droid <281415773+senamakel-droid@users.noreply.github.com>
Co-authored-by: Steven Enamakel <enamakel@tinyhumans.ai>

* Update issue templates for GitHub issue types (tinyhumansai#1146)

* feat(human): expand mascot expressions and tighten reply-speech state machine (tinyhumansai#1147)

* feat(memory): ingestion pipeline + tree-architecture docs + ops/schemas split (tinyhumansai#1142)

* feat(threads): surface live subagent work in parent thread (tinyhumansai#1122) (tinyhumansai#1159)

* fix(human): keep mascot mouth animating when TTS ships no viseme data (tinyhumansai#1160)

* feat(composio): consume backend markdownFormatted for LLM output (tinyhumansai#1165)

* fix(subagent): lazy-register toolkit actions filtered out of fuzzy top-K (tinyhumansai#1162)

* feat(memory): user-facing long-term memory window preset (tinyhumansai#1137) (tinyhumansai#1161)

* fix(tauri-shell): proactively kill stale openhuman RPC on startup (tinyhumansai#1166)

* chore(staging): v0.53.13

* fix(composio): per-action tool consumes backend markdownFormatted (tinyhumansai#1167)

* fix(threads): persist selectedThreadId across reloads (tinyhumansai#1168)

* feat(memory_tree): switch embed model to bge-m3 (1024-dim, 8K context) (tinyhumansai#1174)

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(agent): drop redundant [Memory context] recall injection (tinyhumansai#1173)

* chore(memory_tree): drop body-read timeouts on Ollama HTTP calls (tinyhumansai#1171)

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat(transcript): emit thread_id + fix orchestrator missing cost (tinyhumansai#1169)

* fix(composio/gmail): phase out html2md, prefer text/plain MIME part (tinyhumansai#1170)

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat(tools): markdown output for internal tool results (tinyhumansai#1172)

* feat(security): enforce prompt-injection guard before model and tool execution (tinyhumansai#1175)

* fix(cef): popup paint dies after first frame — skip blank-page guard for popups (tinyhumansai#1079) (tinyhumansai#1182)

Co-authored-by: Steven Enamakel <31011319+senamakel@users.noreply.github.com>

* chore(sentry): rename OPENHUMAN_SENTRY_DSN → OPENHUMAN_CORE_SENTRY_DSN (tinyhumansai#1186)

* feat(remotion): add yellow mascot character with all animation variants (tinyhumansai#1193)

Co-authored-by: Neel Mistry <neelmistry@Neels-MacBook-Pro.local>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* refactor(composio): hide raw connection ID, derive friendly label (tinyhumansai#1153) (tinyhumansai#1185)

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>

* fix(windows): align install.ps1 MSI with per-machine scope (tinyhumansai#913) (tinyhumansai#1187)

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(tauri): deterministic CEF teardown on full app close (tinyhumansai#1120) (tinyhumansai#1189)

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(composio): cap Gmail HTML body before strip (crash mitigation) (tinyhumansai#1191)

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(auth): stop stale chat threads after signup (tinyhumansai#1192)

Co-authored-by: Cursor <cursoragent@cursor.com>

* feat(sentry): staging-only "Trigger Sentry Test" button (tinyhumansai#1072) (tinyhumansai#1183)

* chore(staging): v0.53.14

* chore(staging): v0.53.15

* feat(composio): format trigger slugs into human-readable labels (tinyhumansai#1129) (tinyhumansai#1179)

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>

* fix(ui): hide unsupported permission UI on non-macOS for Screen Intelligence (tinyhumansai#1194)

Co-authored-by: Cursor <cursoragent@cursor.com>

* chore(tauri-shell): retire embedded Gmail webview-account flow (tinyhumansai#1181)

* feat(onboarding): replace welcome-agent bot with react-joyride walkthrough (tinyhumansai#1180)

* chore(release): v0.53.16

* fix(threads): preserve selectedThreadId on cold-boot identity hydration (tinyhumansai#1196)

* feat(core): version/shutdown/update RPCs + mid-thread integration refresh (tinyhumansai#1195)

* fix(mascot): swap to yellow mascot via @remotion/player (tinyhumansai#1200)

* feat(memory_tree): cloud-default LLM, queue priority, entity filter, Memory tab UI (tinyhumansai#1198)

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* Persist turn state + restore conversation history on cold-boot (tinyhumansai#1202)

* feat(mascot): floating desktop mascot via native NSPanel + WKWebView (macOS) (tinyhumansai#1203)

* fix(memory/tree): emit summary children as Obsidian wikilinks (tinyhumansai#1210)

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat(tools): coding-harness baseline primitives (tinyhumansai#1205) (tinyhumansai#1208)

* docs: add Codex PR checklist for remote agents

---------

Co-authored-by: Steven Enamakel <31011319+senamakel@users.noreply.github.com>
Co-authored-by: WOZCODE <contact@withwoz.com>
Co-authored-by: sanil-23 <sanil@vezures.xyz>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Cyrus Gray <144336577+graycyrus@users.noreply.github.com>
Co-authored-by: CodeGhost21 <164498022+CodeGhost21@users.noreply.github.com>
Co-authored-by: oxoxDev <164490987+oxoxDev@users.noreply.github.com>
Co-authored-by: Mega Mind <146339422+M3gA-Mind@users.noreply.github.com>
Co-authored-by: Gaurang Patel <ptelgm.yt@gmail.com>
Co-authored-by: unn-Known1 <unn-known1@users.noreply.github.com>
Co-authored-by: Steven Enamakel <enamakel@tinyhumans.ai>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Steven Enamakel <senamakel@users.noreply.github.com>
Co-authored-by: Steven Enamakel's Droid <enamakel.agent@tinyhumans.ai>
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Co-authored-by: senamakel-droid <281415773+senamakel-droid@users.noreply.github.com>
Co-authored-by: YellowSnnowmann <167776381+YellowSnnowmann@users.noreply.github.com>
Co-authored-by: Neil <neil@maha.xyz>
Co-authored-by: Neel Mistry <neelmistry@Neels-MacBook-Pro.local>
Co-authored-by: obchain <167975049+obchain@users.noreply.github.com>
Co-authored-by: Jwalin Shah <jshah1331@gmail.com>
AusAgentSmith pushed a commit to AusAgentSmith/openhuman that referenced this pull request May 23, 2026
senamakel added a commit to nocstah/openhuman that referenced this pull request Sep 11, 2026
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