Skip to content

feat(composio): per-toolkit tool curation, user scopes, and Gmail HTML→markdown#643

Merged
senamakel merged 16 commits intotinyhumansai:mainfrom
senamakel:feat/skiils-filters
Apr 18, 2026
Merged

feat(composio): per-toolkit tool curation, user scopes, and Gmail HTML→markdown#643
senamakel merged 16 commits intotinyhumansai:mainfrom
senamakel:feat/skiils-filters

Conversation

@senamakel
Copy link
Copy Markdown
Member

@senamakel senamakel commented Apr 18, 2026

Summary

  • Cuts agent tool-list noise: hand-curated whitelists for 27 Composio toolkits (gmail, notion, github, slack, discord, googlecalendar/drive/docs/sheets, outlook, microsoft_teams, linear, jira, trello, asana, dropbox, twitter, spotify, telegram, whatsapp, shopify, stripe, hubspot, salesforce, airtable, figma, youtube). Each curated action is classified read / write / admin.
  • Adds per-user scope preferences stored in KV (composio-user-scopes namespace), keyed by toolkit. Defaults to {read:true, write:true, admin:false}. Enforced at both composio_list_tools (filter) and composio_execute (reject) in src/openhuman/composio/tools.rs.
  • Exposes the prefs over the controller registry: openhuman.composio_get_user_scopes and openhuman.composio_set_user_scopes for the React settings UI to wire up.
  • Adds a per-toolkit post-processor for composio_execute responses; first impl converts Gmail HTML bodies to markdown via html2md, walking the JSON defensively so it survives Composio response-shape changes.

Problem

Composio publishes 60+ actions per toolkit. The agent saw all of them on every turn — burning tokens and frequently picking irrelevant or destructive actions (delete-thread when it meant move-to-trash, modify-IMAP-settings when it meant draft-email). There was also no user-facing knob to gate side-effectful actions per integration. On Gmail, message bodies arrived as raw HTML, costing tokens and making the model parse <table>/<style> noise to find the actual text.

Solution

Curation layer (src/openhuman/composio/providers/):

  • tool_scope.rsToolScope::{Read,Write,Admin}, CuratedTool { slug, scope }, classify_unknown() heuristic for un-curated toolkits, toolkit_from_slug() extractor.
  • gmail/tools.rs, notion/tools.rs, github/tools.rs — provider-owned curated catalogs.
  • catalogs.rs — single file holding the other 24 toolkit catalogs (catalog-only, no native provider yet).
  • catalog_for_toolkit(toolkit) in providers/mod.rs — static dispatch (handles both google_calendargooglecalendar aliasing and MICROSOFT_TEAMS_* extracting to "microsoft" via the action-slug prefix rule).
  • ComposioProvider::curated_tools() (default None) — registered providers can also override.

Scope layer (providers/user_scopes.rs):

  • UserScopePref { read, write, admin }, KV-backed (mirrors sync_state.rs's pattern).
  • load_or_default(toolkit) resolves the active memory client and falls back to defaults if memory isn't initialised yet.
  • New controller schemas get_user_scopes / set_user_scopes in composio/schemas.rs, registered through the existing controller registry per CLAUDE.md's controller-only exposure rule.

Enforcement (composio/tools.rs):

  • evaluate_tool_visibility(slug) resolves toolkit → catalog → curated entry → user pref. Returns Allow / BlockedByScope / NotCurated / PassthroughCheckScope.
  • filter_list_tools_response drops blocked/non-curated entries from the schema returned to the agent.
  • composio_execute rejects blocked / non-curated slugs with structured error messages before the backend call.

Post-processing (providers/post_process.rs):

  • post_process(toolkit, slug, value) dispatcher; gmail walks the JSON, detects HTML strings via cheap substring heuristic (<html, <body, <div, <p>, <table>, …) bounded to the first 4KB, and converts via html2md::parse_html.
  • Hooked into composio_execute after a successful response (errors pass through verbatim).
  • Adds html2md = \"0.2\" (pure Rust, no system deps).

Heavy [composio][scopes] and [composio][post-process] debug logs at filter / enforcement / conversion points so the reduction in tool count and HTML→markdown size are visible per turn.

Submission Checklist

  • Unit testscargo test --lib openhuman::composio:: passes (190 tests, including new coverage for tool_scope, user_scopes, post_process).
  • E2E / integration — JSON-RPC E2E for the new get_user_scopes / set_user_scopes controllers and end-to-end execute filtering is a follow-up; the unit-level coverage exercises the full filter/enforce logic.
  • Doc comments//! on every new module; /// on the new public types and functions.
  • Inline comments — Reasoning notes on the multi-segment toolkit prefix handling, the html-detection heuristic bounds, and the registry-vs-static catalog fallback.

Impact

  • Token reduction: per-turn composio_list_tools payload drops from "every action this toolkit publishes" to a curated subset (typically 15–30 actions vs. 60+). Gmail HTML→markdown additionally cuts message-body bytes substantially on emails with marketing markup.
  • Safety: agent can no longer call destructive toolkit actions until the user opts into the admin scope for that toolkit. Default read+write keeps day-to-day flows working.
  • Compatibility: toolkits without a curated catalog (e.g. twilio) keep current pass-through behaviour, gated by the classify_unknown heuristic against the user pref.
  • Surface: 2 new controller methods exposed on the JSON-RPC registry; no change to existing methods.

Related

  • Issue(s): n/a
  • Follow-up PR(s)/TODOs: wire the read/write/admin toggles in the connect-skill modal in app/; JSON-RPC E2E coverage for the new controllers; consider per-toolkit post-processors for other HTML-heavy responses (outlook bodies, notion page exports).

Summary by CodeRabbit

  • New Features
    • Per-integration permission scopes (Read/Write/Admin) with persisted preferences and UI toggles.
    • Curated tool catalogs expanded (including GitHub, Gmail, Notion and many others) to control tool visibility and execution.
    • Gmail responses: HTML-like fields auto-converted to Markdown during post-processing.
    • New client API endpoints to get/set per-integration scope preferences.
    • Agents can now execute Composio-backed tools (execution allowed via the integration layer).

- Introduced `get_user_scopes` and `set_user_scopes` functions to manage per-toolkit user scope preferences, allowing for read, write, and admin classifications.
- Updated `all_controller_schemas` and `all_registered_controllers` to include new schemas for user scope management.
- Implemented `evaluate_tool_visibility` to determine tool visibility based on user-defined scopes, enhancing security and control over tool actions.
- Added `UserScopePref` struct to store user preferences and integrated it with memory storage for persistence.
- Enhanced existing tools to respect user scope preferences during execution, ensuring actions align with user-defined permissions.

These changes improve the flexibility and security of toolkit interactions, allowing users to customize their access levels for different actions.
- Updated the GMAIL_CURATED constant to include additional tools for reading and writing emails, such as GMAIL_LIST_MESSAGES, GMAIL_LIST_THREADS, GMAIL_GET_ATTACHMENT, and GMAIL_FORWARD_MESSAGE.
- Improved organization of tools by categorizing them under distinct sections for reading messages, managing drafts, and handling labels.
- Enhanced admin tools with new functionalities like GMAIL_BATCH_DELETE_MESSAGES and GMAIL_UNTRASH_THREAD, improving overall email management capabilities.

These changes provide a more comprehensive toolkit for interacting with Gmail, enhancing user experience and functionality.
- Reformatted the `ADMIN` and `GMAIL_CURATED` constants for better readability by aligning the entries vertically.
- Enhanced the clarity of the `classify_unknown` function by improving the structure of the constants, making it easier to maintain and understand.
- Updated test assertions in `toolkit_from_slug` for consistency in formatting, ensuring clearer test outputs.

These changes improve the overall readability and maintainability of the codebase, aligning with ongoing refactoring efforts.
…ration

- Introduced a new GitHub provider module, including a curated catalog of GitHub actions tailored for common tasks such as repository management, issue tracking, and pull request handling.
- Implemented the `catalog_for_toolkit` function to allow fallback to a static curated list for toolkits without a native provider, ensuring consistent tool visibility and access.
- Updated the `evaluate_tool_visibility` function to prioritize curated tools from registered providers, enhancing the overall user experience and security by enforcing whitelist checks.

These changes expand the capabilities of the Composio toolkit, providing users with a comprehensive set of tools for interacting with GitHub, while maintaining a focus on user-defined permissions and visibility.
- Reformatted the `GITHUB_CURATED`, `NOTION_CURATED`, and other tool constants for better readability by aligning entries vertically.
- Enhanced the clarity of the code structure, making it easier to maintain and understand.
- Updated related documentation to reflect the changes in formatting and organization.

These changes improve the overall readability and maintainability of the codebase, aligning with ongoing refactoring efforts.
- Added a new module `catalogs.rs` containing curated tool lists for Slack, Discord, Google Calendar, Google Drive, Google Docs, and more, enhancing the Composio toolkit's integration capabilities.
- Updated the `mod.rs` file to include the new `catalogs` module and modified the `catalog_for_toolkit` function to support these curated lists, allowing for better organization and access to toolkit actions.
- This addition improves the overall functionality and user experience by providing a comprehensive set of tools for interacting with popular platforms.
…esponses

- Introduced a new `post_process` module to handle per-toolkit response modifications, specifically for converting HTML content to markdown format.
- Enhanced the `ComposioExecuteTool` to apply post-processing on successful responses, improving the clarity and usability of data returned from Gmail.
- Added tests to ensure the correct functionality of HTML detection and conversion, validating the integrity of the post-processing logic.

These changes enhance the user experience by streamlining the handling of HTML content in responses, making it more suitable for further processing and display.
…ved readability

- Moved HTML detection markers in the `looks_like_html` function to a more structured format, enhancing clarity and maintainability.
- This change aligns with ongoing efforts to improve code organization and readability within the post-processing module.
…ol constants

- Reformatted the `SLACK_CURATED`, `DISCORD_CURATED`, and `GOOGLECALENDAR_CURATED` constants for improved readability by aligning entries vertically.
- This change enhances the clarity and maintainability of the code, aligning with ongoing refactoring efforts to improve code organization.
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 18, 2026

Warning

Rate limit exceeded

@senamakel has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 0 minutes and 18 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 0 minutes and 18 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 6d1766e4-b1cc-4f87-ae8f-aaa3211600eb

📥 Commits

Reviewing files that changed from the base of the PR and between d1514c4 and c3ad1e9.

📒 Files selected for processing (8)
  • Cargo.toml
  • app/src/components/composio/ComposioConnectModal.tsx
  • app/src/lib/composio/composioApi.ts
  • src/openhuman/composio/providers/post_process.rs
  • src/openhuman/composio/providers/tool_scope.rs
  • src/openhuman/composio/providers/user_scopes.rs
  • src/openhuman/composio/schemas.rs
  • src/openhuman/composio/tools.rs
📝 Walkthrough

Walkthrough

Adds curated per-toolkit action catalogs, provider hooks, per-user KV-backed scope preferences, enforcement in list/execute flows, Gmail HTML→Markdown post-processing, frontend scope UI and RPCs, GitHub curated catalog, and a single Cargo dependency (html2md = "0.2").

Changes

Cohort / File(s) Summary
Core scope & model
src/openhuman/composio/providers/tool_scope.rs, src/openhuman/composio/providers/catalogs.rs
Introduce ToolScope (Read/Write/Admin), CuratedTool, heuristic classification, curated catalog slices, and lookup helpers.
Provider API & wiring
src/openhuman/composio/providers/mod.rs, src/openhuman/composio/providers/traits.rs
New public provider submodules/re-exports, catalog_for_toolkit(), and new trait hook ComposioProvider::curated_tools(). Added is_action_visible_with_pref.
Provider-specific catalogs
src/openhuman/composio/providers/gmail/..., src/openhuman/composio/providers/notion/..., src/openhuman/composio/providers/github/...
Add curated *_CURATED slices for Gmail, Notion, GitHub; Gmail/Notion providers return curated lists via curated_tools().
Per-user preferences & RPC
src/openhuman/composio/providers/user_scopes.rs, src/openhuman/composio/schemas.rs
Add UserScopePref (read/write/admin), KV load/save functions, and controller handlers get_user_scopes / set_user_scopes.
Enforcement & post-processing
src/openhuman/composio/tools.rs, src/openhuman/composio/providers/post_process.rs
Filter composio_list_tools by catalog + user prefs; gate composio_execute on whitelist/scope; run toolkit-specific post-processing (Gmail HTML→Markdown using html2md).
Ops discovery updates
src/openhuman/composio/ops.rs
Apply per-toolkit visibility filtering when building connected integrations and fetching toolkit actions (uses is_action_visible_with_pref).
Frontend integration
app/src/components/composio/ComposioConnectModal.tsx, app/src/lib/composio/composioApi.ts, app/src/lib/composio/types.ts
UI toggles for per-toolkit scopes, RPC wrappers getUserScopes/setUserScopes, and ComposioUserScopePref type.
Agent allowlist & harness
src/openhuman/agent/agents/integrations_agent/agent.toml, src/openhuman/agent/harness/subagent_runner.rs
Add composio_execute to integrations agent allowlist; text-mode tool instructions simplified to omit inline tool listing.
Dependency
Cargo.toml
Added html2md = "0.2" for Gmail HTML→Markdown conversion.

Sequence Diagrams

sequenceDiagram
    actor User
    participant Frontend as Frontend
    participant Agent as Agent Layer
    participant Tools as composio_list_tools
    participant Catalog as catalog_for_toolkit
    participant Backend as Composio Backend
    participant Scope as UserScopePref

    User->>Frontend: Open connect/manage screen
    Frontend->>Agent: Request tool list
    Agent->>Tools: List tools for toolkit
    Tools->>Catalog: Get curated catalog
    Catalog-->>Tools: CuratedTool slice
    Tools->>Backend: List all tools
    Backend-->>Tools: Full tool list
    Tools->>Scope: Load user scope preferences
    Scope-->>Tools: UserScopePref
    Tools->>Tools: Filter tools by catalog & scope
    Tools-->>Agent: Filtered tool list
    Agent-->>Frontend: Display filtered tools and scope toggles
Loading
sequenceDiagram
    actor User
    participant Frontend as Frontend
    participant Agent as Agent Layer
    participant Execute as composio_execute
    participant Catalog as catalog_for_toolkit
    participant Scope as UserScopePref
    participant Backend as Composio Backend
    participant PostProc as post_process

    User->>Frontend: Trigger tool execution
    Frontend->>Agent: Execute slug
    Agent->>Execute: Execute with slug
    Execute->>Catalog: Get curated catalog
    Catalog-->>Execute: CuratedTool slice or None
    alt Not whitelisted
        Execute-->>Agent: Error: tool not whitelisted
    else Whitelisted
        Execute->>Scope: Load user scope preferences
        Scope-->>Execute: UserScopePref
        alt Scope denied
            Execute-->>Agent: Error: scope denied
        else Scope allowed
            Execute->>Backend: Execute action
            Backend-->>Execute: Response data
            Execute->>PostProc: Post-process by toolkit (Gmail: html→md)
            PostProc-->>Execute: Processed data
            Execute-->>Agent: Success result
        end
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested reviewers

  • graycyrus

Poem

🐰 I hopped through catalogs, tidy and spry,

Scopes in my pocket, whitelists nearby.
HTML trimmed to markdown light,
Tools behave morning and night,
A rabbit’s small hop keeps the agent spry. ✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main changes: per-toolkit tool curation, user scope management, and Gmail HTML-to-Markdown conversion.
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.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

…prefs

Adds the three scope toggles to the connected-state of the
ComposioConnectModal so users can gate which Composio actions the
agent may invoke per integration. Loads the stored pref via
`composio_get_user_scopes` once the modal lands in the connected
phase and persists changes through `composio_set_user_scopes` with
optimistic updates and rollback on error.

- Adds `getUserScopes` / `setUserScopes` to composioApi.
- Adds `ComposioUserScopePref` type mirror.
- Renders accessible role="switch" toggles with hint text per row.
- Streamlined the definition of SCOPE_ROWS in ComposioConnectModal by removing unnecessary line breaks, enhancing code readability and maintainability.
- Updated the agent.toml configuration to include "composio_execute" in the tools list, expanding the capabilities of the integrations agent.
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

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 (5)
src/openhuman/composio/providers/tool_scope.rs (1)

86-102: Potential toolkit extraction mismatch for multi-word toolkit slugs.

toolkit_from_slug extracts only the prefix before the first underscore, which works for GMAIL_*"gmail" but may cause issues for toolkits with underscores in their names. For example:

  • MICROSOFT_TEAMS_GET_CHAT"microsoft" (relies on catalog_for_toolkit accepting both "microsoft" and "microsoft_teams")

The catalog_for_toolkit function in mod.rs does handle "microsoft" as a fallback, so this works. However, if Composio ever uses GOOGLE_CALENDAR_* slugs (with underscore) instead of GOOGLECALENDAR_*, those would extract to "google" and miss the catalog lookup entirely.

Consider adding a brief doc comment noting this assumption about slug formats.

📝 Suggested documentation addition
 /// Extract the toolkit slug from a Composio action slug.
 ///
 /// All Composio action slugs follow the convention `<TOOLKIT>_<VERB>_…`
 /// (e.g. `GMAIL_SEND_EMAIL` → `gmail`). Returns the lowercased prefix
 /// before the first underscore, or `None` if the slug has no underscore.
+///
+/// **Note:** Multi-word toolkits like Microsoft Teams use compound prefixes
+/// (`MICROSOFT_TEAMS_*` → `"microsoft"`). The caller should ensure
+/// `catalog_for_toolkit` handles both forms (e.g. `"microsoft"` and
+/// `"microsoft_teams"`).
 pub fn toolkit_from_slug(slug: &str) -> Option<String> {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/openhuman/composio/providers/tool_scope.rs` around lines 86 - 102,
toolkit_from_slug currently splits the slug at the first '_' and lowercases that
prefix which breaks for multi-word toolkit names that themselves contain
underscores; update the function's documentation (near toolkit_from_slug) to
state the assumption that Composio toolkit identifiers must not contain
underscores (e.g., that slugs are of the form `<TOOLKIT>_<VERB>_…` and that
fallback handling is performed by catalog_for_toolkit for known aliases like
"microsoft"), and mention that if multi-word toolkit names with underscores are
expected the extraction logic (toolkit_from_slug) must be revised to consult
catalog_for_toolkit or a mapping instead.
src/openhuman/composio/providers/user_scopes.rs (1)

140-151: Consider logging the toolkit name consistently.

The log at line 145 uses %toolkit (the raw input) while load() logs %key (the normalized key). For consistency and grep-ability, consider logging both or using the normalized key here too.

📝 Suggested consistency improvement
     None => {
+        let key = kv_key(toolkit);
         tracing::debug!(
-            toolkit = %toolkit,
+            toolkit = %key,
             "[composio][scopes] memory not ready, using default pref"
         );
         UserScopePref::default()
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/openhuman/composio/providers/user_scopes.rs` around lines 140 - 151, The
debug log in load_or_default uses the raw toolkit string but load() logs a
normalized key, causing inconsistency; update load_or_default (and its
tracing::debug call) to log the same normalized key that load() emits (or log
both toolkit and normalized key) by reusing the same normalization logic used by
load() so the tracing fields match (reference: load_or_default, load, toolkit,
key, UserScopePref).
Cargo.toml (1)

19-19: Consider html2md crate maintenance status before committing.

The 0.2 version spec is appropriate and will resolve to the latest 0.2.15 release. However, the crate has not been updated in over a year (last update January 2025). While it is stable and widely used (58 reverse dependencies, 500k+ downloads), more actively maintained alternatives exist, such as htmd (v0.5.4, last updated April 2026). If long-term maintenance is a concern, evaluate switching to a more actively developed HTML-to-Markdown converter.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Cargo.toml` at line 19, The Cargo.toml currently pins the html2md dependency
as html2md = "0.2"; evaluate the crate's maintenance before committing by
comparing it to the more actively maintained alternative (htmd v0.5.4): run
cargo audit/ cargo outdated and test replacing html2md with htmd in Cargo.toml,
update any code using the html2md API to the htmd equivalents, run the test
suite and linting, and if htmd is compatible adopt htmd = "0.5" (or keep html2md
= "0.2" with a comment documenting the maintenance decision).
src/openhuman/composio/tools.rs (1)

98-103: Consider using zip for clearer intent.

The index-based retain pattern works correctly but is slightly fragile if keep and resp.tools ever got out of sync. A zip-based approach would be more idiomatic.

♻️ Optional: Alternative using drain_filter pattern
-    let mut idx = 0;
-    resp.tools.retain(|_| {
-        let keep_it = keep[idx];
-        idx += 1;
-        keep_it
-    });
+    let mut i = 0;
+    resp.tools.retain(|_| (keep.get(i).copied().unwrap_or(false), i += 1).0);

Or if you prefer explicit iteration:

resp.tools = resp
    .tools
    .drain(..)
    .zip(keep)
    .filter_map(|(t, k)| k.then_some(t))
    .collect();
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/openhuman/composio/tools.rs` around lines 98 - 103, The current retain
loop uses an external index (idx) to consult the `keep` boolean slice while
mutating `resp.tools`, which is fragile; replace this with a zip-based approach
that pairs each tool with its corresponding boolean (zip `resp.tools` with
`keep`) and then filter/collect only the tools where the boolean is true (or use
drain + zip + filter_map) so you avoid the manual `idx` and make intent clearer;
update the code around `resp.tools`/`keep` and remove `idx` and the `retain`
call.
src/openhuman/composio/schemas.rs (1)

54-55: Add regression coverage for the two new schema keys.

Good wiring in Line 54–55 and Line 105–112. One follow-up: every_known_schema_key_resolves (Line 619+) still omits get_user_scopes and set_user_scopes, so a future match-arm regression for these keys would not be caught.

✅ Suggested test update
     let keys = [
         "list_toolkits",
         "list_connections",
         "authorize",
         "delete_connection",
         "list_tools",
         "execute",
         "get_user_profile",
         "sync",
         "list_trigger_history",
+        "get_user_scopes",
+        "set_user_scopes",
     ];

Also applies to: 105-112

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/openhuman/composio/schemas.rs` around lines 54 - 55, The test
every_known_schema_key_resolves is missing the new schema keys get_user_scopes
and set_user_scopes; update that test to include schemas("get_user_scopes") and
schemas("set_user_scopes") in its expected set so the match-arm regression for
those keys will be caught (search for the function/ test
every_known_schema_key_resolves and add the two schemas("...") entries to the
list/collection it validates).
🤖 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/post_process.rs`:
- Line 76: The current byte-slice `&s[..4096]` can panic on UTF-8 boundaries;
change the truncation to use a UTF-8-safe boundary: compute the safe end via
`s.floor_char_boundary(4096)` (or use `s.get(..4096)` and fall back) and then
set `head` using that boundary (i.e., replace the `let head = if s.len() > 4096
{ &s[..4096] } else { s };` logic to use `s.floor_char_boundary(4096)` or
`s.get(..4096).unwrap_or(s)` so `head` is always a valid UTF-8 slice).

In `@src/openhuman/composio/schemas.rs`:
- Around line 531-551: The new RPC handlers handle_get_user_scopes and
handle_set_user_scopes lack structured debug/trace logs; add stable-prefixed
logs at entry (including method name and toolkit value), on important branches
(e.g., when pref is loaded, when memory client is missing), on errors (log the
error with correlation fields) and on successful exit (including returned pref),
using the same grep-friendly prefix (e.g., "composio:scopes:") and include
fields method and toolkit so the memory-not-ready branch (the
crate::openhuman::memory::global::client_if_ready() None case) logs a clear
error before returning. Use the existing logger used in this module for
structured key=value fields and ensure all new log statements appear in both
handle_get_user_scopes and handle_set_user_scopes around async awaits and before
each early return.

---

Nitpick comments:
In `@Cargo.toml`:
- Line 19: The Cargo.toml currently pins the html2md dependency as html2md =
"0.2"; evaluate the crate's maintenance before committing by comparing it to the
more actively maintained alternative (htmd v0.5.4): run cargo audit/ cargo
outdated and test replacing html2md with htmd in Cargo.toml, update any code
using the html2md API to the htmd equivalents, run the test suite and linting,
and if htmd is compatible adopt htmd = "0.5" (or keep html2md = "0.2" with a
comment documenting the maintenance decision).

In `@src/openhuman/composio/providers/tool_scope.rs`:
- Around line 86-102: toolkit_from_slug currently splits the slug at the first
'_' and lowercases that prefix which breaks for multi-word toolkit names that
themselves contain underscores; update the function's documentation (near
toolkit_from_slug) to state the assumption that Composio toolkit identifiers
must not contain underscores (e.g., that slugs are of the form
`<TOOLKIT>_<VERB>_…` and that fallback handling is performed by
catalog_for_toolkit for known aliases like "microsoft"), and mention that if
multi-word toolkit names with underscores are expected the extraction logic
(toolkit_from_slug) must be revised to consult catalog_for_toolkit or a mapping
instead.

In `@src/openhuman/composio/providers/user_scopes.rs`:
- Around line 140-151: The debug log in load_or_default uses the raw toolkit
string but load() logs a normalized key, causing inconsistency; update
load_or_default (and its tracing::debug call) to log the same normalized key
that load() emits (or log both toolkit and normalized key) by reusing the same
normalization logic used by load() so the tracing fields match (reference:
load_or_default, load, toolkit, key, UserScopePref).

In `@src/openhuman/composio/schemas.rs`:
- Around line 54-55: The test every_known_schema_key_resolves is missing the new
schema keys get_user_scopes and set_user_scopes; update that test to include
schemas("get_user_scopes") and schemas("set_user_scopes") in its expected set so
the match-arm regression for those keys will be caught (search for the function/
test every_known_schema_key_resolves and add the two schemas("...") entries to
the list/collection it validates).

In `@src/openhuman/composio/tools.rs`:
- Around line 98-103: The current retain loop uses an external index (idx) to
consult the `keep` boolean slice while mutating `resp.tools`, which is fragile;
replace this with a zip-based approach that pairs each tool with its
corresponding boolean (zip `resp.tools` with `keep`) and then filter/collect
only the tools where the boolean is true (or use drain + zip + filter_map) so
you avoid the manual `idx` and make intent clearer; update the code around
`resp.tools`/`keep` and remove `idx` and the `retain` call.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: dc4c1b61-4696-476c-92cb-a18918544bfb

📥 Commits

Reviewing files that changed from the base of the PR and between f88d657 and c95a621.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (17)
  • Cargo.toml
  • src/openhuman/composio/providers/catalogs.rs
  • src/openhuman/composio/providers/github/mod.rs
  • src/openhuman/composio/providers/github/tools.rs
  • src/openhuman/composio/providers/gmail/mod.rs
  • src/openhuman/composio/providers/gmail/provider.rs
  • src/openhuman/composio/providers/gmail/tools.rs
  • src/openhuman/composio/providers/mod.rs
  • src/openhuman/composio/providers/notion/mod.rs
  • src/openhuman/composio/providers/notion/provider.rs
  • src/openhuman/composio/providers/notion/tools.rs
  • src/openhuman/composio/providers/post_process.rs
  • src/openhuman/composio/providers/tool_scope.rs
  • src/openhuman/composio/providers/traits.rs
  • src/openhuman/composio/providers/user_scopes.rs
  • src/openhuman/composio/schemas.rs
  • src/openhuman/composio/tools.rs

Comment thread src/openhuman/composio/providers/post_process.rs Outdated
Comment thread src/openhuman/composio/schemas.rs
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

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/components/composio/ComposioConnectModal.tsx (1)

1-1: ⚠️ Potential issue | 🟡 Minor

Pipeline failure: Run Prettier to fix formatting.

The CI check indicates Prettier formatting issues. Run prettier --write to fix code style before merging.

cd app && yarn prettier --write src/components/composio/ComposioConnectModal.tsx src/lib/composio/composioApi.ts
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/src/components/composio/ComposioConnectModal.tsx` at line 1, CI reports
Prettier formatting failures for the Composio component files; run Prettier to
auto-fix formatting issues by executing the suggested command in the repo root
(apply to src/components/composio/ComposioConnectModal.tsx and
src/lib/composio/composioApi.ts) so the ComposioConnectModal component and
related composioApi module conform to the project's Prettier rules before
merging.
🧹 Nitpick comments (3)
app/src/components/composio/ComposioConnectModal.tsx (2)

367-372: Add debug logging for scope toggle operations.

Per coding guidelines, critical checkpoints should be logged. The scope toggle flow involves RPC calls and state transitions but has no client-side logging for debugging.

Add logging in handleToggleScope
   const handleToggleScope = useCallback(
     async (key: keyof ComposioUserScopePref) => {
       if (!scopes || savingScope) return;
+      console.debug('[composio][scopes] toggling', { toolkit: toolkit.slug, key, from: scopes[key] });
       const optimistic: ComposioUserScopePref = { ...scopes, [key]: !scopes[key] };
       setScopes(optimistic);
       setSavingScope(key);
       setScopeError(null);
       try {
         const persisted = await setUserScopes(toolkit.slug, optimistic);
+        console.debug('[composio][scopes] persisted', { toolkit: toolkit.slug, persisted });
         setScopes(persisted);
       } catch (err) {
         // Roll back on failure so the toggle reflects reality.
+        console.warn('[composio][scopes] save failed, rolling back', { toolkit: toolkit.slug, key, err });
         setScopes(scopes);
         const msg = err instanceof Error ? err.message : String(err);
         setScopeError(`Couldn't save ${key} scope: ${msg}`);
       } finally {
         setSavingScope(null);
       }
     },
     [savingScope, scopes, toolkit.slug]
   );

As per coding guidelines: "Add substantial, development-oriented logs while implementing features or fixes so issues are easy to trace end-to-end".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/src/components/composio/ComposioConnectModal.tsx` around lines 367 - 372,
Add development-oriented debug logs to the scope toggle flow by instrumenting
the handleToggleScope function: log the incoming scope id/identifier and
intended new state before the RPC call, log when savingScope state is
set/cleared (savingScope), log the RPC response and the updated scopes array on
success, and log the full error object and scopeError update on failure;
reference ScopeToggles, scopes, savingScope, scopeError and ensure logs include
identifying info (scope id/name and timestamps) and error.stack or error.message
for traceability.

26-30: Use import type for type-only import.

ComposioUserScopePref is only used as a type annotation in this file (state type, props type, function parameter type). It should be imported with import type per coding guidelines.

Fix import
-import {
-  type ComposioConnection,
-  type ComposioUserScopePref,
-  deriveComposioState,
-} from '../../lib/composio/types';
+import type { ComposioConnection, ComposioUserScopePref } from '../../lib/composio/types';
+import { deriveComposioState } from '../../lib/composio/types';

As per coding guidelines: "Use import type for TypeScript type-only imports where appropriate".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/src/components/composio/ComposioConnectModal.tsx` around lines 26 - 30,
The import currently mixes a type-only symbol with a runtime value; change the
import so that ComposioUserScopePref is imported using "import type" (leaving
deriveComposioState as a normal import) — e.g., split the line so type-only
ComposioUserScopePref (and any other purely-annotative types like
ComposioConnection if applicable) are imported with "import type" while
deriveComposioState remains a regular import to satisfy the coding guideline.
app/src/lib/composio/composioApi.ts (1)

103-125: Add debug logging for traceability.

Per coding guidelines, new/changed flows should include debug logs with grep-friendly prefixes for correlation. These RPC calls are critical for the scope enforcement feature but lack any client-side logging.

Add debug logging
 export async function getUserScopes(toolkit: string): Promise<ComposioUserScopePref> {
+  console.debug('[composio][rpc] getUserScopes', { toolkit });
   const raw = await callCoreRpc<unknown>({
     method: 'openhuman.composio_get_user_scopes',
     params: { toolkit },
   });
-  return unwrapCliEnvelope<ComposioUserScopePref>(raw);
+  const result = unwrapCliEnvelope<ComposioUserScopePref>(raw);
+  console.debug('[composio][rpc] getUserScopes result', { toolkit, result });
+  return result;
 }

 export async function setUserScopes(
   toolkit: string,
   pref: ComposioUserScopePref
 ): Promise<ComposioUserScopePref> {
+  console.debug('[composio][rpc] setUserScopes', { toolkit, pref });
   const raw = await callCoreRpc<unknown>({
     method: 'openhuman.composio_set_user_scopes',
     params: { toolkit, ...pref },
   });
-  return unwrapCliEnvelope<ComposioUserScopePref>(raw);
+  const result = unwrapCliEnvelope<ComposioUserScopePref>(raw);
+  console.debug('[composio][rpc] setUserScopes result', { toolkit, result });
+  return result;
 }

As per coding guidelines: "Add substantial, development-oriented logs while implementing features or fixes so issues are easy to trace end-to-end" and "use grep-friendly log prefixes ([feature], domain name, or JSON-RPC method)".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/src/lib/composio/composioApi.ts` around lines 103 - 125, Add
grep-friendly debug logs to both getUserScopes and setUserScopes: before calling
callCoreRpc log the outgoing JSON-RPC method and toolkit (e.g.
processLogger.debug("[composio] calling openhuman.composio_get_user_scopes
toolkit=%s", toolkit)), and after unwrapCliEnvelope log the returned
pref/response (e.g. processLogger.debug("[composio]
openhuman.composio_get_user_scopes response=%o", result)). Do the same for
openhuman.composio_set_user_scopes in setUserScopes (log method, toolkit and
pref being sent, then log the unwrapped response). Use the existing
processLogger (or equivalent) and include the RPC method name in the message for
easy grep correlation.
🤖 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/lib/composio/composioApi.ts`:
- Around line 98-109: Doc comment for the `execute` function is misplaced above
`getUserScopes`; move it so the comment immediately precedes the `execute`
function, or alternatively relocate `getUserScopes` (and `setUserScopes` if
nearby) into the "Read operations" section so the comment ordering reflects
intent; update placement around the symbols `execute`, `getUserScopes`, and
`setUserScopes` to ensure the execute docstring documents `execute` and the read
functions are grouped under the read section.

---

Outside diff comments:
In `@app/src/components/composio/ComposioConnectModal.tsx`:
- Line 1: CI reports Prettier formatting failures for the Composio component
files; run Prettier to auto-fix formatting issues by executing the suggested
command in the repo root (apply to
src/components/composio/ComposioConnectModal.tsx and
src/lib/composio/composioApi.ts) so the ComposioConnectModal component and
related composioApi module conform to the project's Prettier rules before
merging.

---

Nitpick comments:
In `@app/src/components/composio/ComposioConnectModal.tsx`:
- Around line 367-372: Add development-oriented debug logs to the scope toggle
flow by instrumenting the handleToggleScope function: log the incoming scope
id/identifier and intended new state before the RPC call, log when savingScope
state is set/cleared (savingScope), log the RPC response and the updated scopes
array on success, and log the full error object and scopeError update on
failure; reference ScopeToggles, scopes, savingScope, scopeError and ensure logs
include identifying info (scope id/name and timestamps) and error.stack or
error.message for traceability.
- Around line 26-30: The import currently mixes a type-only symbol with a
runtime value; change the import so that ComposioUserScopePref is imported using
"import type" (leaving deriveComposioState as a normal import) — e.g., split the
line so type-only ComposioUserScopePref (and any other purely-annotative types
like ComposioConnection if applicable) are imported with "import type" while
deriveComposioState remains a regular import to satisfy the coding guideline.

In `@app/src/lib/composio/composioApi.ts`:
- Around line 103-125: Add grep-friendly debug logs to both getUserScopes and
setUserScopes: before calling callCoreRpc log the outgoing JSON-RPC method and
toolkit (e.g. processLogger.debug("[composio] calling
openhuman.composio_get_user_scopes toolkit=%s", toolkit)), and after
unwrapCliEnvelope log the returned pref/response (e.g.
processLogger.debug("[composio] openhuman.composio_get_user_scopes response=%o",
result)). Do the same for openhuman.composio_set_user_scopes in setUserScopes
(log method, toolkit and pref being sent, then log the unwrapped response). Use
the existing processLogger (or equivalent) and include the RPC method name in
the message for easy grep correlation.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 127d9891-a73d-4c28-b659-63c2d75b7439

📥 Commits

Reviewing files that changed from the base of the PR and between c95a621 and 6ebe96d.

📒 Files selected for processing (3)
  • app/src/components/composio/ComposioConnectModal.tsx
  • app/src/lib/composio/composioApi.ts
  • app/src/lib/composio/types.ts
✅ Files skipped from review due to trivial changes (1)
  • app/src/lib/composio/types.ts

Comment thread app/src/lib/composio/composioApi.ts
…gent prompt

The agent prompt for integrations_agent was rendering every action
returned by the backend's `composio_list_tools` for each connected
toolkit, bypassing the curation/scope filter that the meta-tool layer
applies. Concretely the GitHub integrations_agent prompt was showing
~500 actions including non-curated entries like
GITHUB_ADD_OR_UPDATE_TEAM_REPOSITORY_PERMISSIONS.

Adds `is_action_visible_with_pref(slug, pref)` — a sync helper that
mirrors the meta-tool layer's decision logic — and applies it in:
- `fetch_connected_integrations_uncached` (bulk session-cached path)
- `fetch_toolkit_actions` (per-toolkit spawn-time path)

One pref load per toolkit (not per action) keeps the cost minimal.
…filter

Simplified the action visibility filter in `fetch_connected_integrations_uncached` by consolidating the filter logic into a single line. This change enhances code readability while maintaining the existing functionality of applying user preferences to the displayed actions.
…e preamble

Text-mode subagent prompts were rendering the tool catalog twice: once
in the prompt template's `## Tools` section (with the richer
`Call as: NAME[arg|arg]` signatures from `prompts::ToolsSection::build`)
and once in `### Available Tools` under `## Tool Use Protocol`
(`Parameters: name:type, ...` format).

For an integrations_agent toolkit spawn (~50 actions) this doubled the
tool listing bytes for no informational gain. Keep only the protocol
preamble (essential for text mode); the catalog stays in `## Tools`.

Removes `summarise_parameters` and `first_line_truncated` which were
the sole consumers, plus the now-unused `std::fmt::Write` import.
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

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/composio/providers/mod.rs (1)

51-74: Minor: Doc comment block placement is disjointed.

The doc comment on lines 51-62 describes catalog_for_toolkit (mentioning "Static toolkit → curated catalog map" and the lookup key convention), but this function appears at line 91. Meanwhile, lines 63-74 document is_action_visible_with_pref which immediately follows at line 75.

Consider moving the catalog_for_toolkit doc block to immediately precede that function:

📝 Suggested reordering
-/// Static toolkit → curated catalog map.
-///
-/// This is consulted by the meta-tool layer alongside any registered
-/// provider's [`ComposioProvider::curated_tools`]. It lets toolkits
-/// without a full native provider (e.g. `github`, which has no sync
-/// logic yet) still benefit from curated whitelisting.
-///
-/// Lookup key is the lowercased prefix returned by
-/// [`toolkit_from_slug`] applied to the action slug — e.g.
-/// `GOOGLECALENDAR_CREATE_EVENT` → `"googlecalendar"`. Multi-segment
-/// prefixes like `MICROSOFT_TEAMS_*` are matched via their first
-/// segment with an extra arm.
 /// Synchronous visibility check for a Composio action slug given a
 /// pre-loaded user scope preference.
 /// ...
 pub fn is_action_visible_with_pref(slug: &str, pref: &UserScopePref) -> bool {
     // ...
 }

+/// Static toolkit → curated catalog map.
+///
+/// This is consulted by the meta-tool layer alongside any registered
+/// provider's [`ComposioProvider::curated_tools`]. ...
 pub fn catalog_for_toolkit(toolkit: &str) -> Option<&'static [CuratedTool]> {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/openhuman/composio/providers/mod.rs` around lines 51 - 74, The doc block
describing "Static toolkit → curated catalog map" and lookup key conventions
should be moved so it immediately precedes the catalog_for_toolkit function
(symbol: catalog_for_toolkit) instead of being placed above
is_action_visible_with_pref; then ensure the shorter doc block about the
synchronous visibility check remains directly above is_action_visible_with_pref
(symbol: is_action_visible_with_pref) so each function's documentation is
adjacent to its implementation and the comments reflect the correct function
responsibilities.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/openhuman/composio/providers/mod.rs`:
- Around line 51-74: The doc block describing "Static toolkit → curated catalog
map" and lookup key conventions should be moved so it immediately precedes the
catalog_for_toolkit function (symbol: catalog_for_toolkit) instead of being
placed above is_action_visible_with_pref; then ensure the shorter doc block
about the synchronous visibility check remains directly above
is_action_visible_with_pref (symbol: is_action_visible_with_pref) so each
function's documentation is adjacent to its implementation and the comments
reflect the correct function responsibilities.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 3e8fc4bc-ba04-4ffc-84cb-4231acbd2a3c

📥 Commits

Reviewing files that changed from the base of the PR and between 6ebe96d and 7457cc6.

📒 Files selected for processing (4)
  • app/src/components/composio/ComposioConnectModal.tsx
  • src/openhuman/agent/agents/integrations_agent/agent.toml
  • src/openhuman/composio/ops.rs
  • src/openhuman/composio/providers/mod.rs
✅ Files skipped from review due to trivial changes (1)
  • src/openhuman/agent/agents/integrations_agent/agent.toml
🚧 Files skipped from review as they are similar to previous changes (1)
  • app/src/components/composio/ComposioConnectModal.tsx

…bug)

Real fixes:
- post_process: walk back to UTF-8 char boundary before truncating to
  4096 bytes; previous `&s[..4096]` could panic mid-codepoint. Adds
  regression test that places a 3-byte char straddling the cutoff.
- composioApi: move misplaced `execute` docstring back above `execute`
  (it had drifted above the new `getUserScopes`).
- schemas: include `get_user_scopes` / `set_user_scopes` in the
  `every_known_schema_key_resolves` test.

Diagnosability:
- schemas: structured `[composio:scopes]` debug/error logs at entry,
  exit, and every early-return in `handle_get_user_scopes` /
  `handle_set_user_scopes` (method + toolkit + pref fields). The
  memory-not-ready branch now logs an error before returning.
- composioApi + ConnectModal: grep-friendly `[composio][scopes]` debug
  logs around getUserScopes / setUserScopes RPC round-trips and the
  toggle handler (old → new state, persisted result, errors).
- user_scopes: load_or_default now logs the same normalized `key` that
  `load()` does, so traces correlate across both code paths.

Cleanups:
- tools: replace external `idx` + `Vec::retain` in
  `filter_list_tools_response` with a drain + zip + filter_map pattern.
- tool_scope: document the no-underscore-in-toolkit-name assumption of
  `toolkit_from_slug`, and call out the `microsoft_teams` alias.
- Cargo.toml: comment on the html2md vs htmd choice.

Pushback (no change):
- Reviewer asked to split the type-only import in ConnectModal into a
  separate `import type` line; ESLint's `no-duplicate-imports` rejects
  that, so the inline `type` form (functionally identical) stays.
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

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/agent/harness/subagent_runner.rs (1)

1717-1742: Update stale rustdoc and remove vestigial specs parameter.

Line 1733 no longer uses tool specs, but the rustdoc above still describes per-parameter rendering. Please align docs with current behavior and consider making this helper zero-arg to avoid misleading call patterns.

Suggested refactor
-/// Format a set of `ToolSpec`s as an XML tool-use protocol block
+/// Format the XML tool-use protocol block for text mode.
 /// appended to the system prompt in text mode. Mirrors
 /// [`crate::openhuman::agent::dispatcher::XmlToolDispatcher::prompt_instructions`]
 /// — same `<tool_call>{…}</tool_call>` format so the existing
 /// `parse_tool_calls` helper understands what the model emits.
 ///
-/// Per-parameter rendering is intentionally **compact**: name, type, a
-/// "required" marker, and a short one-line description if present. We
-/// do **not** serialise the full JSON schema. Composio/Fireworks action
-/// schemas for toolkits like Gmail or Notion run multiple KB each —
-/// embedding them verbatim blows up the prompt past the model's
-/// context window (282k+ tokens for 26 Gmail tools vs a 196k cap).
-/// The compact listing keeps the model informed enough to call tools
-/// correctly while staying within budget. If the model needs deeper
-/// schema detail it can surface the error and the orchestrator will
-/// clarify on the next turn.
-pub(crate) fn build_text_mode_tool_instructions(_specs: &[ToolSpec]) -> String {
+/// Tool names/signatures are rendered by the prompt's `## Tools` section;
+/// this helper only adds call-format instructions.
+pub(crate) fn build_text_mode_tool_instructions() -> String {
-            sys.content
-                .push_str(&build_text_mode_tool_instructions(tool_specs));
+            sys.content
+                .push_str(&build_text_mode_tool_instructions());

As per coding guidelines: “New or changed behavior must ship with matching documentation: add concise rustdoc / code comments where the flow is not obvious, and update AGENTS.md, architecture docs, or feature docs when repository rules or user-visible behavior change.”

Also applies to: 1733-1733

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/openhuman/agent/harness/subagent_runner.rs` around lines 1717 - 1742, The
rustdoc for build_text_mode_tool_instructions is stale and the function no
longer uses the _specs parameter; remove the unused parameter from the function
signature (change pub(crate) fn build_text_mode_tool_instructions(_specs:
&[ToolSpec]) -> String to a zero-arg signature), update all call sites that pass
ToolSpec slices to call the new zero-arg build_text_mode_tool_instructions(),
and revise the function's rustdoc to remove references to per-parameter
rendering and explain that it only emits the protocol explanation (the full tool
catalog is provided by prompts::ToolsSection::build); ensure any tests or docs
referencing the old signature are updated accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/openhuman/agent/harness/subagent_runner.rs`:
- Around line 1717-1742: The rustdoc for build_text_mode_tool_instructions is
stale and the function no longer uses the _specs parameter; remove the unused
parameter from the function signature (change pub(crate) fn
build_text_mode_tool_instructions(_specs: &[ToolSpec]) -> String to a zero-arg
signature), update all call sites that pass ToolSpec slices to call the new
zero-arg build_text_mode_tool_instructions(), and revise the function's rustdoc
to remove references to per-parameter rendering and explain that it only emits
the protocol explanation (the full tool catalog is provided by
prompts::ToolsSection::build); ensure any tests or docs referencing the old
signature are updated accordingly.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: ccb9f909-d4a1-43df-b22d-86c60c03eff6

📥 Commits

Reviewing files that changed from the base of the PR and between 7457cc6 and d1514c4.

📒 Files selected for processing (2)
  • src/openhuman/agent/harness/subagent_runner.rs
  • src/openhuman/composio/ops.rs
✅ Files skipped from review due to trivial changes (1)
  • src/openhuman/composio/ops.rs

@senamakel senamakel merged commit 8f4696b into tinyhumansai:main Apr 18, 2026
6 checks passed
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