Skip to content

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

Merged
senamakel merged 2 commits into
tinyhumansai:mainfrom
M3gA-Mind:fix/gmail-html-body-cap
May 4, 2026
Merged

senamakel merged 2 commits into
tinyhumansai:mainfrom
M3gA-Mind:fix/gmail-html-body-cap

Conversation

@M3gA-Mind

@M3gA-Mind M3gA-Mind commented May 4, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

  • Bound Gmail GMAIL_FETCH_EMAILS HTML post-processing to 512 KiB UTF-8 before noise stripping and the fast HTML→text pass.
  • Emit tracing::warn! when truncation applies and append a short [Email HTML body truncated for processing] note to the markdown field.
  • Align module / provider / test comments with the existing fast stripper path (no html2md).
  • Add unit tests oversized_html_is_truncated_before_processing and truncated_all_whitespace_html_still_emits_truncation_note (truncation note when strip yields empty).
  • CodeRabbit: preserve the truncation marker when cleaned is empty after strip.

Problem

During investigation of #982 (production macOS Intel unexpected quit), a crash report showed the faulting thread as tokio-rt-worker, in Composio Gmail periodic sync → html_email_to_markdown / legacy html2md table handling and runaway realloc, not the main-thread CEF SIGABRT described in the issue title. Large or pathological HTML MIME can still stress memory in strip passes without an input cap.

Solution

  • Truncate oversized HTML at a UTF-8-safe boundary before strip_html_noise_blocks / fast_html_to_text.
  • Log and surface truncation in the reshaped markdown payload so agents/users know content was clipped.

Submission Checklist

  • Tests added or updated — oversized HTML cap + whitespace-only truncation note; existing Gmail post-process behaviour otherwise unchanged.
  • Diff coverage ≥ 80% — pnpm test:coverage and pnpm test:rust completed locally (exit 0).
  • Coverage matrix — N/A: small Rust-only composio post-process change.
  • Related feature matrix — N/A: no matrix row change.
  • No new external network dependencies.
  • Manual smoke — N/A: core composio Gmail reshape only.

Impact

  • Desktop core only: slimmer memory use when Composio returns very large HTML bodies; rare emails over 512 KiB HTML lose tail content (explicitly noted in output).

Related

Made with Cursor

Summary by CodeRabbit

  • Bug Fixes
    • Gmail email extraction now prefers plain-text parts and falls back to a bounded HTML-to-text path for large HTML bodies; oversized HTML is truncated and a truncation notice is included in the output (even when the cleaned result is empty).
  • Documentation
    • Updated Gmail sync docs to describe an HTML→text post-processing pipeline.

Composio can return very large HTML MIME; stripping without a bound risks
OOM. Truncate at 512 KiB UTF-8 with a warning, append a truncation note to
markdown output, and align docs with the fast HTML stripper (no html2md).

Tests: oversized_html_is_truncated_before_processing.
Co-authored-by: Cursor <cursoragent@cursor.com>
@M3gA-Mind
M3gA-Mind requested a review from a team May 4, 2026 16:17
@coderabbitai

coderabbitai Bot commented May 4, 2026 •

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 8abe282b-945d-4bf5-b2f4-fa7497cce730

📥 Commits

Reviewing files that changed from the base of the PR and between 4e2ac43 and ef143aa.

📒 Files selected for processing (2)
  • src/openhuman/composio/providers/gmail/post_process.rs
  • src/openhuman/composio/providers/gmail/post_process_tests.rs
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/openhuman/composio/providers/gmail/post_process_tests.rs

📝 Walkthrough

Walkthrough

Gmail post-processing now prefers text/plain parts and falls back to a bounded, linear HTML→text stripper. HTML input is truncated to MAX_GMAIL_HTML_BODY_BYTES at UTF‑8 boundaries; truncation logs a warning and emits a truncation marker, including when stripping yields empty output.

Changes

Gmail Post-Processing Truncation and HTML Extraction

Layer / File(s) Summary
Data Shape & Constants
src/openhuman/composio/providers/gmail/post_process.rs
Adds pub(super) const MAX_GMAIL_HTML_BODY_BYTES: usize and a UTF‑8-aware truncation helper to cap HTML input bytes before processing.
Core Implementation
src/openhuman/composio/providers/gmail/post_process.rs
html_email_to_markdown now truncates HTML to the byte cap, warns via tracing::warn! on truncation, and appends/returns a truncation-note marker. Comments updated to document plaintext-first preference and a linear HTML stripper (no html2md).
Integration & Wiring
src/openhuman/composio/providers/gmail/provider.rs
Module doc updated from “HTML→md” to “HTML→text” for the post_process_action_result pipeline to reflect the bounded stripper behavior.
Tests & Verification
src/openhuman/composio/providers/gmail/post_process_tests.rs
Test comments adjusted to reflect plaintext-first behavior. New tests: oversized_html_is_truncated_before_processing (verifies head preserved, tail omitted, truncation note present) and truncated_all_whitespace_html_still_emits_truncation_note (ensures marker emitted when stripping yields empty body).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

Suggested reviewers

  • senamakel

Poem

I nibble bytes with careful paws,
Trim the tail without a pause,
Keep the start, note what was lost,
Fast and kind — no hidden cost. 🐇✂️

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Linked Issues check ❓ Inconclusive PR implements defensive handling (HTML size cap + truncation logging) as specified in #982, addressing the suspected crash path in Gmail post-processing without fully addressing Intel-specific investigation objectives. Clarify whether the HTML truncation mitigation alone satisfies #982's root cause investigation or if additional Intel-specific diagnostics are required before closing the issue.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed Title clearly identifies the main change: capping Gmail HTML body size before stripping for crash mitigation.
Out of Scope Changes check ✅ Passed All changes directly support the bounded HTML processing and truncation-note behavior for the Gmail post-processor; documentation updates align with implementation.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ 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 @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: 1

🧹 Nitpick comments (1)
src/openhuman/composio/providers/gmail/post_process_tests.rs (1)

289-303: ⚡ Quick win

Use the production cap constant in the truncation test.

Hardcoding 512 * 1024 makes this test drift-prone if the cap changes. Reusing MAX_GMAIL_HTML_BODY_BYTES keeps intent locked to behavior.

💡 Suggested tweak
 fn oversized_html_is_truncated_before_processing() {
-    const CAP: usize = 512 * 1024;
+    const CAP: usize = MAX_GMAIL_HTML_BODY_BYTES;
     let filler = "x".repeat(600 * 1024);
@@
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/openhuman/composio/providers/gmail/post_process_tests.rs` around lines
289 - 303, The test hardcodes CAP (512 * 1024) instead of using the production
constant MAX_GMAIL_HTML_BODY_BYTES; update the test in post_process_tests.rs to
reference MAX_GMAIL_HTML_BODY_BYTES (import it if necessary) when computing the
cap and the filler length so the generated html exceeds
MAX_GMAIL_HTML_BODY_BYTES, and keep assertions (html_email_to_markdown,
HEAD_MARKER, TAIL_NEVER_SEEN, and truncation note) unchanged.
🤖 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/providers/gmail/post_process.rs`:
- Around line 283-289: The code currently returns early when `cleaned` is empty,
so the `truncated` marker is never appended; change the logic to always
construct an `out` string and only populate it from
`normalize_markdownish_text(&fast_html_to_text(cleaned))` when `cleaned` is
non-empty, then if `truncated` is true append "\n\n[Email HTML body truncated
for processing]" to `out` and return it; update the block around `cleaned`,
`out`, `normalize_markdownish_text`, `fast_html_to_text`, and `truncated`
accordingly so the truncation note is preserved even when `cleaned` is empty.

---

Nitpick comments:
In `@src/openhuman/composio/providers/gmail/post_process_tests.rs`:
- Around line 289-303: The test hardcodes CAP (512 * 1024) instead of using the
production constant MAX_GMAIL_HTML_BODY_BYTES; update the test in
post_process_tests.rs to reference MAX_GMAIL_HTML_BODY_BYTES (import it if
necessary) when computing the cap and the filler length so the generated html
exceeds MAX_GMAIL_HTML_BODY_BYTES, and keep assertions (html_email_to_markdown,
HEAD_MARKER, TAIL_NEVER_SEEN, and truncation note) unchanged.
🪄 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: 2583c7cf-324d-480c-80dd-dc2a20922642

📥 Commits

Reviewing files that changed from the base of the PR and between 995669f and 4e2ac43.

📒 Files selected for processing (3)
  • src/openhuman/composio/providers/gmail/post_process.rs
  • src/openhuman/composio/providers/gmail/post_process_tests.rs
  • src/openhuman/composio/providers/gmail/provider.rs

Comment thread src/openhuman/composio/providers/gmail/post_process.rs
CodeRabbit: if HTML was truncated but noise strip leaves only whitespace,
return the truncation marker instead of an empty string.

Tests: whitespace-only body over cap; use MAX_GMAIL_HTML_BODY_BYTES in tests.
Co-authored-by: Cursor <cursoragent@cursor.com>
@senamakel
senamakel merged commit 1aaa59f into tinyhumansai:main May 4, 2026
20 of 22 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 pushed 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.

Fix the production Mac Intel crash (EXC_CRASH/SIGABRT) in OpenHuman 0.53.4

2 participants