feat(skills): channels grid + integrations card polish; tolerant Composio trigger decode#1112
Conversation
📝 WalkthroughWalkthroughThis PR updates Composio/connect modal copy and toolkit display names, refactors the Skills page to separate Channels and add iMessage support with accompanying tests, tightens USD thresholds to treat <= $0.01 as zero for budget/usage logic and promo banner visibility, and adds resilient Serde deserializers and tests for Composio active trigger fields. ChangesComposio Integration UI & Skills Page refactor
Budget & Usage threshold adjustments
Composio trigger deserialization robustness (Rust)
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 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. Review rate limit: 4/5 reviews remaining, refill in 12 minutes. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
app/src/hooks/useUsageState.ts (1)
79-104:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winAlign
isRateLimitedwith the new near-zero threshold semantics.
usagePct10h/budget flags now treat<= 0.01as zero, butisRateLimitedstill usesfiveHourCapUsd > 0(Line 103). For tiny caps, this can still mark users as rate-limited while other state says effectively zero budget.Suggested fix
const isRateLimited = teamUsage !== null && !teamUsage.bypassCycleLimit && - teamUsage.fiveHourCapUsd > 0 && + teamUsage.fiveHourCapUsd > 0.01 && teamUsage.cycleLimit5hr >= teamUsage.fiveHourCapUsd;🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/src/hooks/useUsageState.ts` around lines 79 - 104, Update isRateLimited to use the same near-zero threshold as the other budget checks: change the fiveHourCapUsd condition in isRateLimited (currently checking fiveHourCapUsd > 0) to use > 0.01, keeping the rest of the logic (!teamUsage.bypassCycleLimit and cycleLimit5hr >= fiveHourCapUsd) unchanged so tiny caps are treated as zero-consistent with usagePct10h and budget flags.
🧹 Nitpick comments (1)
src/openhuman/composio/types.rs (1)
245-264: ⚡ Quick winPlease add regression tests for the new tolerant trigger decoding path.
This path now handles multiple upstream shapes; adding focused tests for string/object variants (especially mixed-key
stateobjects) will protect against silent regressions.Example tests to add
+ #[test] + fn active_trigger_deserializes_string_and_object_fields() { + let raw = json!({ + "id": {"id": "trg_1"}, + "slug": {"slug": "GMAIL_NEW_GMAIL_MESSAGE"}, + "toolkit": {"slug": "gmail", "name": "Gmail"}, + "connectionId": {"id": "conn_1"}, + "state": {"state": "ACTIVE", "id": "meta_ignored"} + }); + let t: ComposioActiveTrigger = serde_json::from_value(raw).unwrap(); + assert_eq!(t.id, "trg_1"); + assert_eq!(t.slug, "GMAIL_NEW_GMAIL_MESSAGE"); + assert_eq!(t.toolkit, "gmail"); + assert_eq!(t.connection_id, "conn_1"); + assert_eq!(t.state.as_deref(), Some("ACTIVE")); + }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/openhuman/composio/types.rs` around lines 245 - 264, Add focused regression tests that exercise the tolerant trigger decoding path in types.rs by covering both string and object variants for fields using de_string_or_object and de_opt_string_or_object (notably the struct fields trigger_config and state), including mixed-key/state-as-object cases and combinations (e.g., state as string, state as object, trigger_config present/absent). Write tests that deserialize representative JSON payloads into the target struct and assert the resulting id/slug/toolkit/connection_id/trigger_config/state values match expectations; include negative cases where malformed shapes should fail if appropriate. Place tests near existing serde tests for composio types and reference the deserializers de_string_or_object and de_opt_string_or_object so future changes to those functions will be covered. Ensure tests are deterministic and cover both Option::None and Some(...) branches for state.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/openhuman/composio/types.rs`:
- Around line 52-53: The loop that picks a string from JSON fields uses a
priority order ["slug","id","name","key","value","state"] which can pick
metadata keys before the actual "state" or "value"; update the selection logic
in the deserialization code that contains the for key in ["slug", "id", "name",
"key", "value", "state"] construct so it prefers "state" and "value" (or
explicitly matches the exact intended field) before metadata keys (or switch to
exact-key matching rather than first-found priority), and apply the same fix at
the other occurrence around lines 259-264 to ensure correct deserialization of
state strings.
---
Outside diff comments:
In `@app/src/hooks/useUsageState.ts`:
- Around line 79-104: Update isRateLimited to use the same near-zero threshold
as the other budget checks: change the fiveHourCapUsd condition in isRateLimited
(currently checking fiveHourCapUsd > 0) to use > 0.01, keeping the rest of the
logic (!teamUsage.bypassCycleLimit and cycleLimit5hr >= fiveHourCapUsd)
unchanged so tiny caps are treated as zero-consistent with usagePct10h and
budget flags.
---
Nitpick comments:
In `@src/openhuman/composio/types.rs`:
- Around line 245-264: Add focused regression tests that exercise the tolerant
trigger decoding path in types.rs by covering both string and object variants
for fields using de_string_or_object and de_opt_string_or_object (notably the
struct fields trigger_config and state), including mixed-key/state-as-object
cases and combinations (e.g., state as string, state as object, trigger_config
present/absent). Write tests that deserialize representative JSON payloads into
the target struct and assert the resulting
id/slug/toolkit/connection_id/trigger_config/state values match expectations;
include negative cases where malformed shapes should fail if appropriate. Place
tests near existing serde tests for composio types and reference the
deserializers de_string_or_object and de_opt_string_or_object so future changes
to those functions will be covered. Ensure tests are deterministic and cover
both Option::None and Some(...) branches for state.
🪄 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: 6618d92a-9ca4-4bea-99e2-903fe6de3cd8
⛔ Files ignored due to path filters (2)
Cargo.lockis excluded by!**/*.lockapp/src-tauri/Cargo.lockis excluded by!**/*.lock
📒 Files selected for processing (7)
app/src/components/composio/ComposioConnectModal.tsxapp/src/components/composio/toolkitMeta.tsxapp/src/components/skills/skillIcons.tsxapp/src/hooks/useUsageState.tsapp/src/pages/Home.tsxapp/src/pages/Skills.tsxsrc/openhuman/composio/types.rs
…grid coverage, prefer state/value keys in tolerant decoder
- Update Skills Notion test for the trimmed modal copy ("Connect your Notion account.").
- Add Skills.channels-grid test covering ChannelTile rendering, setup-modal open, and absence of the Channels chip.
- Address CodeRabbit feedback: `de_opt_string_or_object` now prefers `state`/`value` keys before slug/id metadata.
- Add Rust unit tests for ComposioActiveTrigger string + object payloads.
There was a problem hiding this comment.
🧹 Nitpick comments (1)
app/src/pages/__tests__/Skills.channels-grid.test.tsx (1)
60-63: ⚡ Quick winAvoid scoping these tests with
.rounded-2xl.Both lookups depend on a styling class, so a visual-only refactor will break the suite even if the UI still works. Please switch to a semantic hook on the card and query that instead.
As per coding guidelines,
app/src/**/*.test.{ts,tsx}: Prefer testing behavior over implementation details.Also applies to: 80-83
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/src/pages/__tests__/Skills.channels-grid.test.tsx` around lines 60 - 63, The tests currently scope the card using a styling class via channelsHeading.closest('.rounded-2xl') and then call within(channelsCard as HTMLElement); replace this brittle selector with a semantic hook on the card (e.g., an accessible role/aria-label or existing data-testid like "channels-card") and query that element (e.g., getByRole/getByLabelText/getByTestId) instead, then pass the found element into within(...) using the same within$ variable; make the same replacement for the other occurrence that mirrors lines 80-83 so no tests rely on the '.rounded-2xl' styling class.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@app/src/pages/__tests__/Skills.channels-grid.test.tsx`:
- Around line 60-63: The tests currently scope the card using a styling class
via channelsHeading.closest('.rounded-2xl') and then call within(channelsCard as
HTMLElement); replace this brittle selector with a semantic hook on the card
(e.g., an accessible role/aria-label or existing data-testid like
"channels-card") and query that element (e.g.,
getByRole/getByLabelText/getByTestId) instead, then pass the found element into
within(...) using the same within$ variable; make the same replacement for the
other occurrence that mirrors lines 80-83 so no tests rely on the '.rounded-2xl'
styling class.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: b7fa655d-a47d-4b4f-bad4-c3e48baa5806
📒 Files selected for processing (3)
app/src/pages/__tests__/Skills.channels-grid.test.tsxapp/src/pages/__tests__/Skills.third-party-notion-debug-tools.test.tsxsrc/openhuman/composio/types.rs
🚧 Files skipped from review as they are similar to previous changes (1)
- src/openhuman/composio/types.rs
… ignore unreachable BUILT_IN_SKILLS branches - Drop dead `ConnectionBadge`/`isMessagingId` import (the channel branch in renderGroup is gone now that channels render via ChannelTile). - Mark the unreachable per-id BUILT_IN_SKILLS branches in renderGroup with v8 ignore so diff-cover doesn't count code that can't fire while the list is empty. - Extend the channels-grid test with parameterized cases for connected / connecting / error states so the ChannelTile className branches are covered. - New Skills.discovered-skills test renders user / project / legacy scope rows, asserts the scope-color mapping, that Uninstall only surfaces on user-scope, and that View opens the detail drawer.
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
app/src/pages/Skills.tsx (1)
570-729: 💤 Low valueMissing explicit return for
channelkind inrenderGroupmap.The
items.mapcallback handles'builtin'and'discovered'kinds but has no explicit case for'channel'. While channels are filtered out viaotherGroups(line 550), if one ever slips through due to a future refactor, the callback would implicitly returnundefined, rendering nothing silently.Consider adding an explicit defensive case:
🛡️ Defensive fix
); } + // Channels are rendered in a dedicated card above; skip if one leaks through. + if (item.kind === 'channel') { + return null; + } + return null; // Exhaustive fallback })}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/src/pages/Skills.tsx` around lines 570 - 729, The map callback over items (items.map) currently handles 'builtin' and 'discovered' but lacks an explicit branch for item.kind === 'channel', which can lead to an implicit undefined return; add a defensive case for channel inside the same map (or a final else) that explicitly returns either a UnifiedSkillCard representing the channel (using item.id, item.icon, item.name, item.description and navigate(item.route!)) or returns null while logging a warning (e.g., console.warn('[skills] unexpected channel item', { id: item.id })) so the intent is explicit and no implicit undefined is rendered; update the code paths that set secondaryActions/onCtaClick accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@app/src/pages/__tests__/Skills.channels-grid.test.tsx`:
- Around line 35-41: The current mocks point to the wrong module and are dead —
remove the vi.mock calls that target the unused module paths and instead add a
mock for the actual API used by Skills.tsx: mock the skillsApi module so that
skillsApi.listSkills is stubbed (resolve to an empty list or fixture) and also
mock skillsApi.installSkill if the test expects it; ensure the test imports use
the mock by creating a vi.mock for the real skillsApi module and providing
listSkills and installSkill fakes so the component effect
(skillsApi.listSkills()) is driven by the test rather than the real API.
---
Nitpick comments:
In `@app/src/pages/Skills.tsx`:
- Around line 570-729: The map callback over items (items.map) currently handles
'builtin' and 'discovered' but lacks an explicit branch for item.kind ===
'channel', which can lead to an implicit undefined return; add a defensive case
for channel inside the same map (or a final else) that explicitly returns either
a UnifiedSkillCard representing the channel (using item.id, item.icon,
item.name, item.description and navigate(item.route!)) or returns null while
logging a warning (e.g., console.warn('[skills] unexpected channel item', { id:
item.id })) so the intent is explicit and no implicit undefined is rendered;
update the code paths that set secondaryActions/onCtaClick accordingly.
🪄 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: da4ce6f8-ce70-4473-ae77-65d48a5ef933
📒 Files selected for processing (3)
app/src/pages/Skills.tsxapp/src/pages/__tests__/Skills.channels-grid.test.tsxapp/src/pages/__tests__/Skills.discovered-skills.test.tsx
CodeRabbit flagged the `lib/skills/*` mocks as dead — Skills.tsx imports from `services/api/skillsApi`, so swap to the matching factory (mirrors Skills.discovered-skills.test.tsx) to keep listSkills off the network.
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
app/src/pages/__tests__/Skills.channels-grid.test.tsx (1)
122-128: ⚡ Quick winPrefer behavior assertions over container class-name matching here.
expect(telegramTile.className).toMatch(...)is brittle to style refactors and ties the test to Tailwind internals. Assert observable status/CTA semantics instead (accessible name/text), which is what users actually experience.Suggested refactor
- expect(telegramTile.className).toMatch(classPattern); + expect(telegramTile).toHaveAccessibleName( + new RegExp(`Telegram.*${labelPattern.source}`, 'i') + ); + if (status === 'connected') { + expect(telegramTile).toHaveAccessibleName(/Manage/i); + } else { + expect(telegramTile).toHaveAccessibleName(/Setup/i); + }As per coding guidelines: "Prefer testing behavior over implementation details; use existing helpers from
app/src/test/before adding new harness code".🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/src/pages/__tests__/Skills.channels-grid.test.tsx` around lines 122 - 128, The test is asserting on the DOM className (telegramTile.className) which is brittle; replace that with behavior-focused assertions: locate the Telegram tile via the existing telegramTile variable (found with within(...).getByRole('button', ...)) and assert its accessible semantics instead — e.g., that the button's accessible name/text matches labelPattern (using toHaveAccessibleName or checking .textContent), that any status is exposed via aria attributes (aria-pressed/aria-checked/aria-disabled) or that the expected CTA/button state is present, and/or assert that clicking the button triggers the expected handler; remove the classPattern assertion and prefer existing test helpers from app/src/test/ for accessibility assertions.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@app/src/pages/__tests__/Skills.channels-grid.test.tsx`:
- Around line 122-126: The test calls within(channelsCard as HTMLElement) after
const channelsCard = screen.getByRole(...).closest('.rounded-2xl') but closest
can return null; add an explicit non-null guard before using within to produce a
clear failure. Locate the channelsCard variable in the test and add a check
(e.g., expect(channelsCard).not.toBeNull() or if (!channelsCard) throw new
Error(...)) immediately after the closest(...) call, then safely cast
channelsCard to HTMLElement before calling within(...) to find telegramTile via
getByRole.
---
Nitpick comments:
In `@app/src/pages/__tests__/Skills.channels-grid.test.tsx`:
- Around line 122-128: The test is asserting on the DOM className
(telegramTile.className) which is brittle; replace that with behavior-focused
assertions: locate the Telegram tile via the existing telegramTile variable
(found with within(...).getByRole('button', ...)) and assert its accessible
semantics instead — e.g., that the button's accessible name/text matches
labelPattern (using toHaveAccessibleName or checking .textContent), that any
status is exposed via aria attributes (aria-pressed/aria-checked/aria-disabled)
or that the expected CTA/button state is present, and/or assert that clicking
the button triggers the expected handler; remove the classPattern assertion and
prefer existing test helpers from app/src/test/ for accessibility assertions.
🪄 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: 52c3267d-4386-41ac-809f-f5967d79cdaa
📒 Files selected for processing (1)
app/src/pages/__tests__/Skills.channels-grid.test.tsx
* 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>
…osio trigger decode (tinyhumansai#1112)
Summary
ComposioActiveTriggerdeserialization tolerant of upstream API shape drift (e.g.toolkitarriving as an object instead of a string), fixing the runtimeCouldn't load triggers: ... invalid type: map, expected a stringerror in the modal.Problem
composio_list_triggersstarted failing at runtime because Composio now returns objects (e.g.toolkit: { slug: ... }) where our struct expected plain strings, blocking the trigger toggles inside the connect modal.Solution
ChannelTilemirrorsComposioConnectorTilestyling (12×12 icon, name, status label, sage outline when connected) so Channels and Integrations look like one cohesive surface.de_string_or_object/de_opt_string_or_objecthelpers insrc/openhuman/composio/types.rsaccept either a string or an object (extractingslug/id/name/key), applied toComposioActiveTrigger'sid,slug,toolkit,connection_id, andstatefields.Submission Checklist
Impact
Summary by CodeRabbit
New Features
Improvements
Tests