Skip to content

Composio memory sync advertises 31 toolkits but implements 6 — unsupported connections fail silently #106

Description

@M3gA-Mind

Important

The pipeline body goes in tinyhumansai/tinycortex; the wiring goes here. This is a cross-repo deliverable.

How a Composio memory-source sync is actually built (Gmail is the worked example):

Piece Lives in Job
Enginerun_incremental_sync(source: &dyn IncrementalSource, …) (vendor/tinycortex/src/memory/sync/orchestrator.rs:113) tinycortex paging, incremental filtering, ingestion — generic, toolkit-agnostic
PipelineGmailSyncPipeline (vendor/tinycortex/src/memory/sync/composio/gmail.rs:18, ~229 lines) tinycortex implements SyncPipeline + IncrementalSource; answers toolkit-specific questions (toolkit()"gmail", action()GMAIL_FETCH_EMAILS, arguments(), extract_page()). Its tick() is one line — it hands itself to the engine
ProviderComposioProvider (src/openhuman/memory_sync/composio/providers/gmail/) openhuman account/profile, daily request budget, HTML→text post-processing, cursor/state; delegates ingestion to tinycortex
Selector — the match at src/openhuman/tinycortex/sync.rs:344 openhuman maps a toolkit slug → pipeline. A missing arm is what raises tinycortex sync does not support toolkit '<slug>'

Placement decision: the pipeline body lands in tinycortex, alongside the existing six (gmail, github, notion, linear, clickup, slack). To be precise about why: this is a deliberate consistency decision, not a technical constraintIncrementalSource is an unsealed pub trait over public types (orchestrator.rs:53-104) and the engine takes a trait object, so openhuman could legally implement a pipeline locally under the orphan rule. We are keeping all pipeline bodies in one repo instead.

Order of work:

  1. tinyhumansai/tinycortex — implement the pipeline (SyncPipeline + IncrementalSource), register it, cut a release.
  2. tinyhumansai/openhuman — bump the vendor/tinycortex submodule pointer (pinned at 9a0603af), add the sync.rs:344 arm, and register the ComposioProvider so memory_sources.supported_toolkits advertises the slug.

This issue stays on openhuman because step 2 is here and this is where the user-visible failure surfaces. Do not close it on the tinycortex release alone — it is done when the slug actually syncs end to end.

Dedupe (read before writing): set metadata.path_scope to a stable collection scope; per-item IDs are dedupe keys only. PR tinyhumansai/openhuman#4953 fixed exactly this bug class (stable document_id as the upsert key) — do not reintroduce it.

Coordinate with tinyhumansai/openhuman#4993, which adds a drift guard asserting the advertised set == the syncable set. As each pipeline registers, its slug moves from "advertised but not syncable" to both.


Summary

Composio memory-source sync supports 6 of the 31 toolkits the app advertises. Connecting any of the other 25 succeeds, reports ACTIVE, and then fails silently at sync time — the user sees a connected source that never produces memory.

Problem

src/openhuman/tinycortex/sync.rs:344-353 selects a sync pipeline from a hardcoded match:

let pipeline: Arc<dyn SyncPipeline> = match toolkit.as_str() {
    "gmail" => GmailSyncPipeline::new(...),
    "github" => GitHubSyncPipeline::new(...),
    "notion" => NotionSyncPipeline::new(...),
    "linear" => LinearSyncPipeline::new(...),
    "clickup" => ClickUpSyncPipeline::new(...),
    "slack" => SlackSyncPipeline::new(...),
    _ => return Err(format!("tinycortex sync does not support toolkit '{toolkit}'")),
};

Meanwhile CAPABILITY_TOOLKITS (src/openhuman/memory_sync/composio/providers/mod.rs:63) advertises 31 toolkits.

Supported (6): gmail github notion linear clickup slack

Missing (25): discord googlecalendar googledrive googledocs googlesheets outlook microsoft_teams jira trello asana dropbox twitter spotify telegram whatsapp shopify stripe hubspot salesforce airtable figma youtube one_drive excel todoist

Observed failure (real session, prod)

Connecting Google Calendar and Google Sheets — both connections created cleanly and went ACTIVE:

[composio:bus] connection_created toolkit=googlecalendar connection_id=ca_tKoh9ongrfYC
[composio:bus] connection observed active; invalidating + eagerly warming integrations cache toolkit=googlecalendar status=ACTIVE
[composio:bus] connection_created toolkit=googlesheets connection_id=ca_LOb1alPJSS-O

…then, at sync:

ERR [observability] memory_sources.sync failed: composio sync failed:
    tinycortex sync does not support toolkit 'googlecalendar'
ERR [observability] memory_sources.sync failed: composio sync failed:
    tinycortex sync does not support toolkit 'googlesheets'

The connect flow gives no hint that sync is unsupported. The failure only appears in a background sync error, so the UI shows a healthy connected source that silently never ingests. This is the mechanism behind tinyhumansai/openhuman#4947 ("only Gmail appears from Composio").

Solution

Two separable pieces:

  1. Stop advertising what cannot sync (the bug). memory_sources.supported_toolkits already exists (src/openhuman/memory_sources/rpc.rs:567) and returns the registered provider slugs, and AddMemorySourceDialog.tsx:77 already intends to consume it — but unsupported toolkits are still connectable. Either filter the picker to the supported set, or surface a clear "sync not supported yet" state instead of a silent background failure. This is the user-facing defect and should land first; it does not require writing any new pipeline.
  2. Add the missing pipelines (feature work). One issue per toolkit, linked below. Each needs a SyncPipeline impl (fetch → map to memory documents → stable dedupe key via path_scope) plus registration.

Note _ => Err(...) is the correct fail-closed default — the defect is advertising 31 while implementing 6, not the match itself.

Acceptance criteria

  • No silent failures — a user can never connect a memory source that cannot sync without being told, in the connect flow.
  • Registry is the single source of truth — the advertised set derives from registered providers, not a second hardcoded list that can drift.
  • Per-toolkit issues — each missing pipeline tracked separately (linked below) and closed as it lands.
  • Regression coverage — a test asserting the advertised set and the syncable set cannot diverge.

Related

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions