Skip to content

feat(composio): curate OneDrive/Excel/Todoist + UI preview badge for uncurated toolkits (#2283)#2361

Merged
senamakel merged 13 commits into
tinyhumansai:mainfrom
CodeGhost21:fix/2283-uncurated-toolkit-catalogs
May 23, 2026
Merged

feat(composio): curate OneDrive/Excel/Todoist + UI preview badge for uncurated toolkits (#2283)#2361
senamakel merged 13 commits into
tinyhumansai:mainfrom
CodeGhost21:fix/2283-uncurated-toolkit-catalogs

Conversation

@CodeGhost21
Copy link
Copy Markdown
Contributor

@CodeGhost21 CodeGhost21 commented May 20, 2026

Summary

  • Add curated agent-ready catalogs for OneDrive, Excel, Todoist so the agent has a usable tool surface for these toolkits.
  • Add a "Preview" badge on the Skills grid for connected toolkits that lack a catalog so users see the limitation before / instead of running into the max-iterations failure documented in Uncurated connected toolkits fail through max iterations #2283.
  • Expose a new RPC composio.list_agent_ready_toolkits as the single source of truth for the UI guard.
  • Scope coordination: PR fix(composio): fail fast for uncurated empty toolkits #2293 (open, CodeRabbit-approved) handles the orthogonal "fast-fail for empty toolkits" slice this PR explicitly defers.

Problem

OneDrive, Excel, Todoist (plus ~90 other Composio toolkits) can be connected in the UI but have no curated backend catalog. composio_list_tools returns no usable actions for them, the agent keeps trying to recover, burns through max_iterations = 10, and surfaces a generic max-iterations error instead of a clear "toolkit not supported" message.

Solution

Rust core

  • New src/openhuman/composio/providers/catalogs_microsoft.rs with ONE_DRIVE_CURATED (16 actions) + EXCEL_CURATED (18 actions), Read/Write/Admin scoped.
  • Append TODOIST_CURATED (22 actions) to catalogs_productivity.rs.
  • Wire the three new toolkits into catalog_for_toolkit (including the ONE_DRIVE_*"one" multi-segment prefix alias, mirroring the microsoft_teams pattern) and CAPABILITY_TOOLKITS.
  • New agent_ready_toolkits() helper + composio.list_agent_ready_toolkits RPC returns sorted slugs.

Frontend

  • listAgentReadyToolkits RPC wrapper + useAgentReadyComposioToolkits() hook (one-shot fetch, cached) → returns Set<string>.
  • ComposioConnectorTile renders a small "Preview" badge with tooltip "Agent integration coming soon" for toolkits without a curated catalog. Badge does not block authorization.
  • English i18n strings added; the new follow-up commit seeds the same keys into all 11 non-English locale chunks so the i18n-coverage script stops reporting drift.
  • Updated 5 existing Skills.*.test.tsx mocks of lib/composio/hooks to include the new hook (with loading: true so legacy aria-label assertions keep passing).

Submission Checklist

If a section does not apply to this change, mark the item as N/A with a one-line reason.

  • Tests added or updated (happy path + at least one failure / edge case) — 9 new Rust tests + 5 new Vitest tests + 5 legacy Skills tests updated to mock the new hook. cargo test --lib composio::providers composio::schemas composio::ops_test → 263 passed, 0 failed. pnpm test src/lib/composio src/pages/__tests__/Skills → 17 files, 50 tests passing.
  • Diff coverage ≥ 80% — every new branch in agent_ready_toolkits, catalog_for_toolkit (new aliases), and the new hook/RPC wrapper has at least one focused test. UI tile change (Preview badge) is small and exercised via the existing Skills tests.
  • Coverage matrix updated — N/A: behaviour-only additions to existing composio catalog and Skills-grid surface; no new feature row added/removed/renamed.
  • All affected feature IDs from the matrix are listed in ## Related — N/A: no matrix row touched.
  • No new external network dependencies introduced — all changes use the existing JSON-RPC core ⇄ frontend bridge.
  • Manual smoke checklist updated if this touches release-cut surfaces — N/A: catalog additions + tile-decoration change; no impact on release smoke flows.
  • Linked issue closed via Closes #NNN in the ## Related section — see below.

Impact

  • Runtime/platform: backend composio domain + Skills page.
  • User-visible: OneDrive / Excel / Todoist actions now appear in the agent's tool surface when connected. Connected-but-uncurated toolkits get a "Preview" badge instead of letting the agent burn through max iterations.
  • Performance / security: zero runtime cost — agent_ready_toolkits is a static slice; the hook fetches once per session and caches.
  • Migration / compatibility: new RPC is additive; existing composio.list_toolkits and composio.list_capabilities are unchanged.

Tests

  • Rust (9 new): catalog uniqueness + scope coverage for OneDrive/Excel/Todoist; catalog_for_toolkit resolves the new slugs including the ONE_DRIVE_*one prefix alias; capability matrix integration; agent_ready_toolkits() ordering + content.
  • Vitest (5 new + 5 legacy mocks updated): RPC wrapper success/missing-field paths; hook returns correct Set on success / empty Set on failure; existing Skills page tests now mock the new hook.

cargo test --lib composio::providers composio::schemas composio::ops_test263 passed, 0 failed.
pnpm test src/lib/composio src/pages/__tests__/Skills17 files, 50 tests passing.
pnpm exec tsx scripts/i18n-coverage.ts → no drift on the new keys.

Related


AI Authored PR Metadata (required for Codex/Linear PRs)

Linear Issue

Commit & Branch

  • Branch: fix/2283-uncurated-toolkit-catalogs (branched from origin/main after fresh fetch)
  • Commit SHA: see PR head

Validation Run

  • pnpm --filter openhuman-app format:check — applied via prettier hook (commit fb94e08f).
  • pnpm typecheck — clean.
  • Focused tests: cargo test --lib composio → 263 passed; pnpm test src/lib/composio src/pages/__tests__/Skills → 50 passed.
  • Rust fmt/check (if changed): cargo fmt --manifest-path Cargo.toml applied; cargo check clean.
  • Tauri fmt/check (if changed): N/A — no app/src-tauri/ changes.

Validation Blocked

  • command: N/A
  • error: N/A
  • impact: N/A

Behavior Changes

  • Intended behavior change: OneDrive / Excel / Todoist gain curated agent catalogs; connected-but-uncurated toolkits show a Preview badge on the Skills grid.
  • User-visible effect: the agent can now act on those three toolkits via Composio; the Skills grid distinguishes agent-ready from preview tiles.

Parity Contract

  • Legacy behavior preserved: existing curated catalogs, composio.list_toolkits, and composio.list_capabilities are unchanged. Legacy Skills page tests pass with the same aria-label and role text.
  • Guard/fallback/dispatch parity checks: loading: true default for the new hook in test mocks keeps Preview badges off so legacy assertions don't drift.

Duplicate / Superseded PR Handling

Summary by CodeRabbit

  • New Features

    • Added OneDrive, Excel, and Todoist toolkits and agent-ready detection; UI now shows a "Preview" badge/tooltip for non‑agent-ready toolkits (title/aria-label updated). Badges are suppressed while loading and fallback gracefully on errors.
  • Tests

    • Added/updated tests for agent-ready listing, normalization, hook behavior, and Skills page badge rendering.
  • Localization

    • Added preview badge and tooltip translations across multiple languages.

Review Change Stack

…uncurated toolkits (tinyhumansai#2283)

Adds curated agent-ready catalogs for OneDrive, Excel, and Todoist
so the agent has a usable tool surface when users connect them, and
introduces a "Preview" badge on the Skills grid for connected
toolkits that lack a catalog so users aren't led into the
max-iterations failure documented in tinyhumansai#2283.

Refs tinyhumansai#2283. PR tinyhumansai#2293 handles the agent-side fast-fail; this PR
covers the catalog + UI guard slices that tinyhumansai#2293 explicitly defers.

Rust
- New `catalogs_microsoft.rs` with ONE_DRIVE_CURATED + EXCEL_CURATED.
- Append TODOIST_CURATED to catalogs_productivity.rs.
- Wire the three new toolkits into `catalog_for_toolkit`
  (including the `ONE_DRIVE_*` → "one" multi-segment prefix alias)
  and `CAPABILITY_TOOLKITS`.
- New `agent_ready_toolkits()` helper + RPC
  `composio.list_agent_ready_toolkits` → returns sorted slugs with
  curated catalogs. Single source of truth for the UI guard.
- Docstrings on the new catalogs document the no-profile / no-sync /
  no-memory-ingest contract (criterion tinyhumansai#6 in the issue).

Frontend
- `listAgentReadyToolkits` RPC wrapper + `useAgentReadyComposioToolkits`
  hook (one-shot fetch, cached) → returns `Set<string>`.
- `ComposioConnectorTile` renders a "Preview" badge with tooltip
  "Agent integration coming soon" when the toolkit is not
  agent-ready. While the fetch is in flight we treat every toolkit
  as agent-ready to avoid a flash of badges on the curated tiles.
- i18n: `composio.previewBadge`, `composio.previewTooltip` (English;
  other locales fall back via existing `en` fallback chain).

Tests
- 9 new Rust tests covering catalog uniqueness, scope coverage,
  toolkit→catalog resolution (including the ONE_DRIVE prefix alias),
  capability matrix integration, and `agent_ready_toolkits()`
  ordering + content.
- 5 new Vitest tests for the API wrapper + the hook's success,
  failure, and missing-field paths.

`cargo check` clean. `cargo fmt` applied. `tsc --noEmit` clean.
@CodeGhost21 CodeGhost21 requested a review from a team May 20, 2026 18:30
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 20, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds curated catalogs (OneDrive/Excel/Todoist), a backend RPC to list agent-ready toolkits, a typed frontend API wrapper and hook to fetch canonical slugs, and a Skills page preview badge driven by the new hook and i18n strings.

Changes

Agent-Ready Composio Toolkits Feature

Layer / File(s) Summary
Type definitions and response contract
app/src/lib/composio/types.ts, src/openhuman/composio/types.rs
Frontend and backend add ComposioAgentReadyToolkitsResponse with toolkits: string[].
Backend RPC operation and schema registration
src/openhuman/composio/ops.rs, src/openhuman/composio/schemas.rs
Implements composio_list_agent_ready_toolkits, registers schema/handler, and returns typed JSON from the controller.
Microsoft OneDrive/Excel and Todoist curated catalogs
src/openhuman/composio/providers/catalogs_microsoft.rs, src/openhuman/composio/providers/catalogs_productivity.rs
Adds ONE_DRIVE_CURATED, EXCEL_CURATED, and TODOIST_CURATED with scope mappings and unit tests for non-empty, unique slugs and scope coverage.
Provider module integration and capability matrix
src/openhuman/composio/providers/mod.rs, src/openhuman/composio/providers/catalogs.rs, src/openhuman/composio/providers/descriptions.rs, src/openhuman/composio/mod.rs
Exports new catalogs, updates CAPABILITY_TOOLKITS, catalog_for_toolkit, and agent_ready_toolkits(), and adds tests validating resolution and capability-matrix rows.
Frontend API wrapper for RPC call
app/src/lib/composio/composioApi.ts, app/src/lib/composio/composioApi.test.ts
Adds listAgentReadyToolkits() that calls the RPC and unwraps envelope-style responses; tests verify envelope unwrapping and flat responses.
Frontend hook for agent-ready toolkit management
app/src/lib/composio/hooks.ts, app/src/lib/composio/hooks.test.ts
Implements useAgentReadyComposioToolkits to fetch and canonicalize slugs into a ReadonlySet, track loading/error, and avoid state updates after unmount; tests cover success, error, and missing-field cases.
Skills page UI integration and preview badge rendering
app/src/pages/Skills.tsx, app/src/lib/i18n/*, app/src/pages/__tests__/*
Calls the hook on Skills page, adds isAgentReady prop to tiles, computes showPreviewBadge, conditionally renders a preview badge with i18n-backed label and tooltip, and updates tests to mock the hook during loading/error.

Sequence Diagram(s)

sequenceDiagram
  participant SkillsUI as Skills Page
  participant Hook as useAgentReadyComposioToolkits
  participant Api as composioApi.listAgentReadyToolkits
  participant Backend as openhuman.composio_list_agent_ready_toolkits
  SkillsUI->>Hook: mount -> fetch agent-ready set
  Hook->>Api: listAgentReadyToolkits()
  Api->>Backend: openhuman.composio_list_agent_ready_toolkits (RPC)
  Backend->>Backend: agent_ready_toolkits() (catalog lookup)
  Backend-->>Api: RpcOutcome<ComposioAgentReadyToolkitsResponse>
  Api-->>Hook: ComposioAgentReadyToolkitsResponse (flat toolkits[])
  Hook-->>SkillsUI: agentReady set, loading/error flags
  SkillsUI->>SkillsUI: render tiles (showPreviewBadge computed per tile)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • tinyhumansai/openhuman#507: Both PRs touch app/src/lib/composio/composioApi.ts’s RPC response handling—PR #507 introduces a shared CLI-envelope unwrapping path used by the new listAgentReadyToolkits().

Suggested labels

rust-core

Suggested reviewers

  • graycyrus
  • senamakel

Poem

🐰 New toolkits hop into view, neat and spry,
OneDrive, Excel, Todoist waving hi.
A badge that whispers "Preview" to the crowd,
Fetch, canonicalize, and show — humble and proud.
Tests pass, catalogs sing — a carrot-shaped high-five!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title accurately summarizes the main change: adding curated catalogs for OneDrive/Excel/Todoist and introducing a UI preview badge for uncurated toolkits.
Linked Issues check ✅ Passed The PR successfully addresses all primary coding objectives from issue #2283: OneDrive/Excel/Todoist catalogs are added [catalogs_microsoft.rs, catalogs_productivity.rs], agent-ready toolkit list is implemented [composio_list_agent_ready_toolkits RPC], and UI preview badges are rendered for uncurated toolkits [Skills.tsx, ComposioConnectorTile].
Out of Scope Changes check ✅ Passed All changes are within scope: backend catalogs, RPC endpoint, frontend hooks, UI rendering, i18n entries, and regression tests directly support the curated catalog and preview badge objectives from #2283.
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.


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

@coderabbitai coderabbitai Bot added the feature Net-new user-facing capability or product behavior. label May 20, 2026
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

🧹 Nitpick comments (2)
src/openhuman/composio/providers/mod.rs (1)

219-265: ⚡ Quick win

Avoid duplicating the canonical agent-ready slug list.

agent_ready_toolkits() currently hardcodes a second copy of toolkit membership. Deriving it from existing canonical data (CAPABILITY_TOOLKITS + catalog_for_toolkit) will prevent future drift that could mislabel toolkits in the UI.

♻️ Proposed refactor
 pub fn agent_ready_toolkits() -> Vec<&'static str> {
-    let mut slugs: Vec<&'static str> = vec![
-        // Native providers
-        "gmail",
-        "notion",
-        "github",
-        // Catalog-only toolkits
-        "slack",
-        "discord",
-        "googlecalendar",
-        "googledrive",
-        "googledocs",
-        "googlesheets",
-        "outlook",
-        "microsoft_teams",
-        "linear",
-        "jira",
-        "trello",
-        "asana",
-        "dropbox",
-        "twitter",
-        "spotify",
-        "telegram",
-        "whatsapp",
-        "shopify",
-        "stripe",
-        "hubspot",
-        "salesforce",
-        "airtable",
-        "figma",
-        "youtube",
-        "one_drive",
-        "excel",
-        "todoist",
-    ];
+    let mut slugs: Vec<&'static str> = CAPABILITY_TOOLKITS
+        .iter()
+        .copied()
+        .filter(|toolkit| catalog_for_toolkit(toolkit).is_some())
+        .collect();
     slugs.sort_unstable();
+    slugs.dedup();
     slugs
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/openhuman/composio/providers/mod.rs` around lines 219 - 265, The function
agent_ready_toolkits() duplicates the canonical toolkit list; instead derive the
set from the existing canonical sources by collecting keys from
CAPABILITY_TOOLKITS (native/registered toolkits) and adding any toolkit slugs
that have a curated catalog via catalog_for_toolkit(), deduplicate,
sort_unstable() for stable ordering, and return that Vec<&'static str>; update
references to use CAPABILITY_TOOLKITS and catalog_for_toolkit (or the
appropriate functions/types) so the agent-ready list stays in sync with the
canonical data.
app/src/lib/composio/composioApi.test.ts (1)

156-170: ⚡ Quick win

Assert the sorted contract explicitly.

At Line 167-169, toContain checks membership only, so unsorted/duplicated output would still pass. Since this endpoint is meant to be a stable sorted source, assert full order.

♻️ Proposed test tightening
-    expect(out.toolkits).toContain('excel');
-    expect(out.toolkits).toContain('one_drive');
-    expect(out.toolkits).toContain('todoist');
+    expect(out.toolkits).toEqual(['excel', 'gmail', 'one_drive', 'todoist']);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/src/lib/composio/composioApi.test.ts` around lines 156 - 170, The test
for listAgentReadyToolkits uses toContain which only checks membership and can
miss ordering or duplicates; update the test to assert the exact sorted array is
returned after the envelope is unwrapped (i.e., verify out.toolkits equals
['excel','gmail','one_drive','todoist'] in that order) and keep the existing
mockCallCoreRpc call assertion to ensure the RPC method is correct.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@app/src/pages/Skills.tsx`:
- Around line 333-340: The current consumer of useAgentReadyComposioToolkits
treats an empty agentReadyToolkits (when agentReadyLoading is false) as "not
curated", causing curated toolkits to show Preview; change the logic so that
when agentReadyLoading is false and agentReadyToolkits is empty you treat this
as an RPC failure and fall back to assuming curated toolkits are agent-ready (or
surface an explicit error flag). Concretely, either update
useAgentReadyComposioToolkits to return an error or hasFailed flag (in addition
to agentReady and loading) and use that here, or modify the rendering branch
that reads agentReadyToolkits/agentReadyLoading to detect non-loading empty
results and default curated toolkit slugs to agent-ready instead of marking them
as Preview.

---

Nitpick comments:
In `@app/src/lib/composio/composioApi.test.ts`:
- Around line 156-170: The test for listAgentReadyToolkits uses toContain which
only checks membership and can miss ordering or duplicates; update the test to
assert the exact sorted array is returned after the envelope is unwrapped (i.e.,
verify out.toolkits equals ['excel','gmail','one_drive','todoist'] in that
order) and keep the existing mockCallCoreRpc call assertion to ensure the RPC
method is correct.

In `@src/openhuman/composio/providers/mod.rs`:
- Around line 219-265: The function agent_ready_toolkits() duplicates the
canonical toolkit list; instead derive the set from the existing canonical
sources by collecting keys from CAPABILITY_TOOLKITS (native/registered toolkits)
and adding any toolkit slugs that have a curated catalog via
catalog_for_toolkit(), deduplicate, sort_unstable() for stable ordering, and
return that Vec<&'static str>; update references to use CAPABILITY_TOOLKITS and
catalog_for_toolkit (or the appropriate functions/types) so the agent-ready list
stays in sync with the canonical data.
🪄 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: 6cf69d14-d423-40fa-b62b-2ac43677e41f

📥 Commits

Reviewing files that changed from the base of the PR and between cc498d1 and fb94e08.

📒 Files selected for processing (16)
  • app/src/lib/composio/composioApi.test.ts
  • app/src/lib/composio/composioApi.ts
  • app/src/lib/composio/hooks.test.ts
  • app/src/lib/composio/hooks.ts
  • app/src/lib/composio/types.ts
  • app/src/lib/i18n/en.ts
  • app/src/pages/Skills.tsx
  • src/openhuman/composio/mod.rs
  • src/openhuman/composio/ops.rs
  • src/openhuman/composio/providers/catalogs.rs
  • src/openhuman/composio/providers/catalogs_microsoft.rs
  • src/openhuman/composio/providers/catalogs_productivity.rs
  • src/openhuman/composio/providers/descriptions.rs
  • src/openhuman/composio/providers/mod.rs
  • src/openhuman/composio/schemas.rs
  • src/openhuman/composio/types.rs

Comment thread app/src/pages/Skills.tsx Outdated
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)
app/src/lib/i18n/chunks/en-5.ts (1)

444-445: 💤 Low value

Consider adding a period for consistency.

Most complete-sentence tooltips in this file end with a period (e.g., lines 28, 31, 234). Adding one here would maintain consistency.

📝 Suggested change
   'composio.previewTooltip':
-    'Agent integration coming soon — you can connect, but the agent can't use this toolkit yet',
+    'Agent integration coming soon — you can connect, but the agent can't use this toolkit yet.',
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/src/lib/i18n/chunks/en-5.ts` around lines 444 - 445, The tooltip string
for the key 'composio.previewTooltip' is missing a terminal period; update the
value for 'composio.previewTooltip' so the sentence ends with a period (preserve
the current wording and the trailing comma after the string) to match the other
full-sentence tooltips' punctuation.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@app/src/lib/i18n/chunks/en-5.ts`:
- Around line 444-445: The tooltip string for the key 'composio.previewTooltip'
is missing a terminal period; update the value for 'composio.previewTooltip' so
the sentence ends with a period (preserve the current wording and the trailing
comma after the string) to match the other full-sentence tooltips' punctuation.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 6591977f-4c5a-4eeb-9e0d-03ac5e1b5a8b

📥 Commits

Reviewing files that changed from the base of the PR and between fb94e08 and 34a6fc6.

📒 Files selected for processing (1)
  • app/src/lib/i18n/chunks/en-5.ts

…eed locale chunks

CI was failing on:
  * test / Frontend Unit Tests — 5 Skills.* test files exploded
    because they mock `lib/composio/hooks` but never added the new
    `useAgentReadyComposioToolkits` export that this PR added to
    Skills.tsx. The page imported `undefined`, called it, and
    React crashed before the asserted tiles could render.
  * test / i18n Coverage — the two new English keys
    (`composio.previewBadge`, `composio.previewTooltip`) lived in
    `en.ts` + `en-5.ts` but were missing from all 11 non-English
    locale chunks, so the strict coverage script reported
    `missing[head]` 11 times.

Tests
- Added a stub `useAgentReadyComposioToolkits: () => ({ agentReady:
  new Set<string>(), loading: true, error: null })` to the five
  `Skills.*.test.tsx` files that mock `lib/composio/hooks`.
- `loading: true` is deliberate: it triggers the Skills.tsx
  early-return that treats every tile as agent-ready and skips the
  Preview-badge render. That preserves the pre-tinyhumansai#2283 aria-label /
  role text these legacy tests assert on, so nothing else needs to
  change.
- SkillsStep.test.tsx does not render `<Skills />` and does not
  import the new hook — its mock didn't need updating.

i18n
- Inserted the two new keys with English placeholder values into
  the 11 non-English locale chunks (`ar`, `bn`, `es`, `fr`, `hi`,
  `id`, `it`, `ko`, `pt`, `ru`, `zh-CN` — all `-5.ts`), right after
  the sibling `composio.reconnect` row so the per-chunk position
  matches `en-5.ts`. They flow through the existing translator
  workflow as "untranslated" entries (the i18n coverage script
  surfaces them as such for translators).

Verification
- `pnpm test src/pages/__tests__/Skills` → 5 files, 12 tests
  passing.
- `pnpm exec tsx scripts/i18n-coverage.ts` reports `missing: 0`
  across all locales for the new keys; the only remaining drift is
  the pre-existing "unused English keys" warning that's been there
  before this PR.
@coderabbitai coderabbitai Bot added the agent Built-in agents, prompts, orchestration, and agent runtime in src/openhuman/agent/. label May 20, 2026
…ully when agent-ready RPC fails

CodeRabbit major finding on app/src/pages/Skills.tsx.
Before this fix, when `useAgentReadyComposioToolkits` failed
(loading: false, agentReady empty, error set), Skills.tsx
evaluated `isAgentReady = false` for every tile and the
integrations grid lit up with Preview badges across every curated
toolkit — actively misrepresenting the agent surface during a
transient RPC failure.

Fix
- Destructure `error` from the hook (it was already exposed on the
  return shape; just unused) and treat any non-null error as a
  signal to fall back to "agent-ready" so curated tiles render
  without the badge. The UI degrades to the pre-tinyhumansai#2283 behaviour
  instead of misleading users.
- New predicate:
    isAgentReady =
      agentReadyLoading
      || Boolean(agentReadyError)
      || agentReadyToolkits.has(meta.slug)

Tests
- `Skills.composio-catalog.test.tsx`: route the agent-ready hook
  through a module-level `agentReadyState` so individual tests
  can flip `loading` / `error`. Default state preserves legacy
  test behaviour (`loading: true`).
- New `does not flood the integrations grid with Preview badges
  when the agent-ready RPC fails` asserts no `data-testid`
  starting with `composio-preview-badge-` is rendered anywhere in
  the integrations grid when the hook reports an error.

`pnpm test src/pages/__tests__/Skills` → 5 files, 13 tests passing
(12 pre-existing + 1 new regression).
coderabbitai[bot]
coderabbitai Bot previously approved these changes May 20, 2026
Copy link
Copy Markdown
Contributor

@graycyrus graycyrus left a comment

Choose a reason for hiding this comment

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

Review — graycyrus

Solid PR. The three new curated catalogs (OneDrive, Excel, Todoist) are well-structured, scope-tagged, and follow the existing catalog patterns. The Preview badge UX is a clean guard that directly addresses the user confusion documented in #2283. The error-fallback path CodeRabbit flagged has been fixed. Test coverage is strong across both Rust and the frontend.

Changes summary

Area Files What changed
Rust catalogs catalogs_microsoft.rs (new), catalogs_productivity.rs, catalogs.rs, mod.rs OneDrive (16 actions), Excel (18), Todoist (22) catalogs + wiring into catalog_for_toolkit + agent_ready_toolkits() helper
Rust RPC ops.rs, schemas.rs, types.rs, mod.rs New composio.list_agent_ready_toolkits RPC endpoint
Frontend API/hooks composioApi.ts, hooks.ts, types.ts listAgentReadyToolkits RPC wrapper + useAgentReadyComposioToolkits hook
Frontend UI Skills.tsx Preview badge on uncurated tiles, graceful degradation on RPC failure
i18n en.ts, en-5.ts, + 11 locale chunks New composio.previewBadge and composio.previewTooltip keys
Tests 7 test files 14 new tests + 5 legacy mock updates

Blocking concern

[major] Closes #2283 will auto-close the issue prematurely. This PR addresses acceptance criteria 1–4 and 7–8, but criterion 5 ("No silent max-iteration loop — agent fails fast with a user-friendly unsupported-toolkit message") is explicitly deferred to companion PR #2293. When this PR merges, GitHub will auto-close #2283, and the remaining fast-fail work could be forgotten. Please change to Part of #2283 or Addresses #2283 so the issue stays open until #2293 also lands.

CodeRabbit dedup

CodeRabbit flagged the RPC-failure fallback (Preview badges flooding curated tiles when the hook errors out). This was addressed in commits 5fe07d0–afbb6d7 with the Boolean(agentReadyError) guard. Not repeated here.


Nice work overall — the catalog data, RPC plumbing, hook, and UI integration are all clean. The two inline items below are minor but worth addressing before merge.

/// Returned in sorted order to keep the RPC response stable across
/// builds.
pub fn agent_ready_toolkits() -> Vec<&'static str> {
let mut slugs: Vec<&'static str> = vec![
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.

[minor] agent_ready_toolkits() manually duplicates the set of toolkit slugs that catalog_for_toolkit() already knows about. If someone adds a new catalog match arm to catalog_for_toolkit but forgets to add it here, the UI will incorrectly show a Preview badge on a curated toolkit.

The existing test agent_ready_toolkits_includes_new_catalogs_and_is_sorted partially guards against this, but it only checks specific slugs — it won't catch a newly added toolkit that nobody thought to assert on.

Suggestion: consider deriving this list from catalog_for_toolkit by probing CAPABILITY_TOOLKITS (which already lists all supported slugs), or add a test that asserts agent_ready_toolkits() is a superset of CAPABILITY_TOOLKITS. That way a new entry in one place is automatically reflected in both.

'webhooks.tunnels.toggleFailed': 'فشل تبديل الصدى',
'composio.authExpired': 'انتهت صلاحية المصادقة',
'composio.reconnect': 'إعادة الاتصال',
'composio.previewBadge': 'Preview',
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.

[minor] All 11 non-English locale files have the English text verbatim for both composio.previewBadge and composio.previewTooltip. "Preview" as a badge might be intentional (brand term), but the tooltip — "Agent integration coming soon — you can connect, but the agent can't use this toolkit yet" — should be translated. As-is, Arabic, Bengali, Hindi, Chinese, etc. users will see an English tooltip that defeats the purpose of the i18n system.

If translations aren't ready yet, that's fine — but consider adding a // TODO: translate marker so the i18n-coverage script or a follow-up sweep picks them up.

@senamakel senamakel self-assigned this May 22, 2026
Addresses @coderabbitai nitpick on app/src/lib/i18n/chunks/en-5.ts:444 —
most complete-sentence tooltips in this chunk end with a period; the new
composio.previewTooltip was missing one. Applied to en.ts and all 11
non-English locale chunks that mirror the English copy.
/// Source of truth for the UI "preview / agent integration coming
/// soon" badge: any connected toolkit whose slug is NOT in this list
/// can be authorized but lacks a curated tool surface, so the agent
/// can't use it productively.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Reviewed this nitpick (also raised by @coderabbitai). Deferring the structural change to the author: agent_ready_toolkits() deliberately diverges from CAPABILITY_TOOLKITS — the existing test on this file explicitly asserts !slugs.contains("clickup") even though clickup has a curated catalog and a native provider. Auto-deriving the list from CAPABILITY_TOOLKITScatalog_for_toolkit would flip clickup to agent-ready, which appears to be intentional behavior. If that exclusion is no longer wanted, the right follow-up is to (a) clarify clickup's status, then (b) collapse the lists. Leaving as-is for this PR.

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.

@senamakel, understood — the divergence is intentional. clickup is in CAPABILITY_TOOLKITS (so it appears in the capability matrix as a native provider) but is deliberately excluded from agent_ready_toolkits(), and the existing test explicitly guards that exclusion. Auto-deriving the agent-ready list from CAPABILITY_TOOLKITS ∩ catalog_for_toolkit would silently promote clickup to agent-ready before its status is resolved. The comment + test together serve as a clear deferred-work marker, so leaving the two lists separate for now is the right call.


✏️ Learnings added
Learnt from: senamakel
Repo: tinyhumansai/openhuman PR: 2361
File: src/openhuman/composio/providers/mod.rs:229-229
Timestamp: 2026-05-22T23:13:33.943Z
Learning: In `src/openhuman/composio/providers/mod.rs`, `agent_ready_toolkits()` deliberately diverges from `CAPABILITY_TOOLKITS`. Specifically, `clickup` appears in `CAPABILITY_TOOLKITS` (has a native provider + curated catalog) but is intentionally excluded from `agent_ready_toolkits()`. The test `agent_ready_toolkits_includes_new_catalogs_and_is_sorted` explicitly asserts `!slugs.contains(&"clickup")`. Do NOT suggest auto-deriving `agent_ready_toolkits()` from `CAPABILITY_TOOLKITS ∩ catalog_for_toolkit`, as that would flip `clickup` to agent-ready prematurely. The structural collapse of the two lists is deferred until `clickup`'s agent-ready status is explicitly clarified.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.


🧠 Learnings used
Learnt from: sanil-23
Repo: tinyhumansai/openhuman PR: 416
File: src/openhuman/memory/relex.rs:441-464
Timestamp: 2026-04-07T15:49:51.275Z
Learning: When using the `ort` Rust crate v2.x with the `load-dynamic` feature enabled, don’t require individual execution-provider feature flags (e.g., `directml`, `coreml`, `cuda`) alongside `load-dynamic` to get EP registration code. The `ort` crate already compiles EP registration via `#[cfg(any(feature = "load-dynamic", feature = "<ep_name>"))]` guards, and adding per-EP feature flags can pull in static-linking dependencies that conflict with the dynamic loading approach. At runtime, EP availability is determined by what the dynamically loaded ONNX Runtime library (`onnxruntime.dll`/`.so`/`.dylib`) supports; ort docs indicate providers like `directml`/`xnnpack`/`coreml` are available in builds when the platform supports them.

Learnt from: sanil-23
Repo: tinyhumansai/openhuman PR: 416
File: src/openhuman/memory/relex.rs:441-464
Timestamp: 2026-04-07T15:49:51.275Z
Learning: When integrating the `ort` Rust crate v2.x with the `load-dynamic` feature enabled, do NOT also require/enable individual provider EP Cargo features like `directml`, `coreml`, or `cuda`. In `ort` v2.x, EP registration for providers (e.g., DirectML, CoreML, CUDA, etc.) is already compiled in under source-level `#[cfg(any(feature = "load-dynamic", feature = "<provider>"))]` guards, such as in `ep/directml.rs`. Adding provider feature flags alongside `load-dynamic` can pull in static-linking dependencies that conflict with the dynamic-loading approach. Provider availability should be treated as runtime-determined by what the loaded `onnxruntime` library (`onnxruntime.dll`/`libonnxruntime.so`/`libonnxruntime.dylib`) actually supports.

Learnt from: oxoxDev
Repo: tinyhumansai/openhuman PR: 571
File: src/openhuman/local_ai/service/whisper_engine.rs:69-80
Timestamp: 2026-04-14T19:59:04.826Z
Learning: When reviewing Rust code in this repo that uses the upstream `whisper-rs` crate (v0.16.0), do not report `WhisperContextParameters::use_gpu(...)` or `WhisperContextParameters::flash_attn(...)` as missing/invalid APIs. These builder-style methods exist upstream and return `&mut Self`; they are not limited to `WhisperVadContextParams`.

Learnt from: graycyrus
Repo: tinyhumansai/openhuman PR: 1078
File: src/openhuman/agent/agents/welcome/prompt.rs:24-24
Timestamp: 2026-05-01T13:41:00.958Z
Learning: For Rust code under `src/openhuman/**/*.rs`, use `snake_case` for local variables (not `camelCase`). If a local variable name is written in `camelCase`, treat it as a style/lint issue because it will trigger Rust’s `non_snake_case` warning (and related clippy linting, if enabled). Avoid suggesting `camelCase` for any Rust local variable names in this repository.

Learnt from: senamakel
Repo: tinyhumansai/openhuman PR: 1173
File: tests/agent_memory_loader_public.rs:88-88
Timestamp: 2026-05-04T06:50:47.877Z
Learning: In this repository, the general camelCase naming guideline should not be applied to Rust source files. For all .rs files, Rust function (and related) names should use snake_case, and snake_case Rust function names should not be flagged—even for async test functions annotated with attributes like #[tokio::test]. This is consistent with Rust’s non_snake_case lint behavior.

Learnt from: sanil-23
Repo: tinyhumansai/openhuman PR: 1825
File: src/openhuman/composio/tools.rs:1028-1039
Timestamp: 2026-05-15T22:00:07.176Z
Learning: In `src/openhuman/composio` Rust code, avoid relying on a captured `Arc<Config>` for runtime behavior that depends on the current on-disk config. For any `execute()`/client-creation path (e.g., `ProviderContext::execute()` and `ProviderContext::backend_client()`), reload the live config at the start of each invocation using `config_rpc::load_config_with_timeout()` before calling `create_composio_client()`. Treat any `Arc<Config>` stored on `self` as init-time reference only (not for mode selection/key lookup). In tests that assert behavior driven by `load_config_with_timeout()`, isolate config reads by using the `TEST_ENV_LOCK` + an `OPENHUMAN_WORKSPACE` tempdir, and call `config.save()` so the per-call reload reads a deterministic snapshot.

'webhooks.tunnels.toggleFailed': 'فشل تبديل الصدى',
'composio.authExpired': 'انتهت صلاحية المصادقة',
'composio.reconnect': 'إعادة الاتصال',
'composio.previewBadge': 'Preview',
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Deferring: the PR description explicitly calls out the English-text seeding as intentional ("the new follow-up commit seeds the same keys into all 11 non-English locale chunks so the i18n-coverage script stops reporting drift"). Adding a // TODO: translate marker across 11 files would itself drift the chunks vs the script's expected shape. The right follow-up is a dedicated i18n sweep PR that translates these two keys (and other recently-added English-only strings) in one pass.

@coderabbitai coderabbitai Bot added the rust-core Core Rust runtime in src/: CLI, core_server, shared infrastructure. label May 22, 2026
senamakel added 2 commits May 22, 2026 17:31
…t stale uncurated test

Two CI failures from the merge of main into pr/2361:

1. i18n Coverage + I18nContext/coverage Vitest tests: the original PR seeded
   composio.previewBadge/previewTooltip into 11 non-English locale chunks but
   missed German (de-5.ts). Add them with the same English placeholder pattern
   the other chunks use, so the missing-key gate is satisfied.

2. openhuman::composio::tools::tests::empty_uncurated_toolkits_message_names_agent_unsupported_toolkits:
   this test was added on main to assert the uncurated-toolkit message names
   onedrive/excel/todoist — but this PR curates those three, so they're no
   longer uncurated and uncatalogued_toolkits filters them out, returning None.
   Repoint the test at slugs that remain uncurated (sharepoint, monday,
   intercom). Companion test empty_uncurated_toolkits_message_ignores_catalogued_toolkits
   already covers the gmail/googlesheets curated path.
# Conflicts:
#	app/src/pages/Skills.tsx
#	src/openhuman/composio/providers/catalogs.rs
@senamakel senamakel merged commit e9c9374 into tinyhumansai:main May 23, 2026
23 of 25 checks passed
senamakel added a commit to justinhsu1477/openhuman that referenced this pull request May 23, 2026
…merge

Commit e9c9374 (tinyhumansai#2361) accidentally removed all settings.developerMenu.mcpServer.*
and settings.mcpServer.* keys from de-5.ts, leaving German as the only locale
without translations for the MCP server settings panel. Other locales
(en, ar, bn, es, fr, hi, id, it, ko, pt, ru, zh-CN) still have them.

Restored the 18 missing keys with the same German translations they
had before tinyhumansai#2361.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agent Built-in agents, prompts, orchestration, and agent runtime in src/openhuman/agent/. feature Net-new user-facing capability or product behavior. rust-core Core Rust runtime in src/: CLI, core_server, shared infrastructure.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Uncurated connected toolkits fail through max iterations

3 participants