Repository navigation
feat(core): version/shutdown/update RPCs + mid-thread integration refresh - #1195
Conversation
…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.
📝 WalkthroughWalkthroughAdds 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. ChangesGraceful Shutdown Flow
Composio Tools & Connected Integrations
Update Domain: version / run
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
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
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
src/openhuman/update/ops.rs (1)
69-73: 💤 Low valueSilent loss of error context when serialization fails.
If
serde_json::to_value(&result)fails, returningValue::Nulldiscards both the originalUpdateRunResultand the serialization error. The same pattern appears at lines 93, 130, and 175. Consider logging or embedding the error like the fallback inupdate_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
⛔ Files ignored due to path filters (1)
app/src-tauri/Cargo.lockis excluded by!**/*.lock
📒 Files selected for processing (15)
src/core/event_bus/events.rssrc/core/jsonrpc.rssrc/openhuman/agent/harness/subagent_runner/ops.rssrc/openhuman/composio/tools.rssrc/openhuman/composio/tools_tests.rssrc/openhuman/service/bus.rssrc/openhuman/service/mod.rssrc/openhuman/service/ops.rssrc/openhuman/service/schemas.rssrc/openhuman/service/shutdown.rssrc/openhuman/tools/impl/agent/spawn_subagent.rssrc/openhuman/update/core.rssrc/openhuman/update/ops.rssrc/openhuman/update/schemas.rssrc/openhuman/update/types.rs
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.
There was a problem hiding this comment.
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
📒 Files selected for processing (3)
src/openhuman/agent/harness/subagent_runner/ops.rssrc/openhuman/composio/tools.rssrc/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
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.
There was a problem hiding this comment.
🧹 Nitpick comments (1)
src/openhuman/tools/impl/agent/spawn_subagent.rs (1)
234-242: 💤 Low valueComment 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
📒 Files selected for processing (4)
src/openhuman/agent/harness/subagent_runner/ops.rssrc/openhuman/composio/mod.rssrc/openhuman/composio/ops.rssrc/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
* 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>
Summary
update.version,update.run,service.shutdownso the desktop frontend can ask the running core what version it is, trigger a one-call check → stage → restart, or gracefully exit it.service.restartalready existed.composio_list_toolsnow 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.spawn_subagentintegrations 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:
update.checkandupdate.applyfor 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.composio_list_toolsis 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.connected_integrationsVec 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 fromparent.connected_integrations, thespawn_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 }fromCARGO_PKG_VERSION+ the existingplatform_triple()helper. No network. Cheap discovery.update.run— orchestrates check → stage → restart in one call. Re-uses the existingvalidate_download_url/validate_asset_namesafety net so the orchestrator can't bypass the gatesupdate.applyalready enforces. ReturnsUpdateRunResult { applied, staged_path, restart_requested, message, … }.service.shutdown— mirrorsservice.restart: publishes a newSystemShutdownRequestedevent variant, consumed by aShutdownSubscriberthat callsprocess::exit(0)after a 150 ms flush window. Subscriber wired incore/jsonrpc.rs::register_domain_subscribersnext to the existing restart one.composio_list_toolsmarkdown + connected-onlyrender_tools_markdowngroups tools by toolkit (parsed from slug prefix), shows\`SLUG\` — description **req:** a, b **opt:** c, dper tool, drops the full JSON parameter schemas. Wired throughexecute_with_options+supports_markdown=trueso the harness picks it up only whenprefer_markdownis set; raw JSON is still the primaryoutput()for direct CLI/RPC callers.include_unconnected: boolparameter (defaultfalse). When false the tool callslist_connections()after fetching tools and drops any tool whose toolkit isn't in the user'sACTIVE/CONNECTEDset. Mirrors the same status allowlistcomposio_list_connectionsuses. Surfacing an error (instead of silently returning[]) if the connections fetch fails so the agent can retry withinclude_unconnected=true.Mid-thread integration refresh
INTEGRATIONS_CACHEonce OAuth reachesACTIVE(viaComposioConnectionCreatedSubscriber). The miss was purely the parent session's stale in-memory Vec.spawn_subagent.rs'sintegrations_agenttoolkit gate AND insubagent_runner::run_typed_mode, fetch the live list viacomposio::fetch_connected_integrations(&config)instead of readingparent.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.Submission Checklist
docs/TESTING-STRATEGY.mdpnpm test:rust+pnpm test:coveragelocally and address ifdiff-coverflags anything below 80%.docs/TESTING-STRATEGY.md)RELEASE-MANUAL-SMOKE.mdImpact
update.apply+service.restarttwo-step.composio_list_toolsmarkdown output materially shortens responses — expected ~50–80% smaller depending on toolkit. The connected-only default avoids surfacing actions the user can't actually call.Related
Summary by CodeRabbit
New Features
Bug Fixes