diff --git a/app/src/components/intelligence/MemorySources.tsx b/app/src/components/intelligence/MemorySources.tsx index 833337ebc..d4d8d26be 100644 --- a/app/src/components/intelligence/MemorySources.tsx +++ b/app/src/components/intelligence/MemorySources.tsx @@ -21,7 +21,7 @@ * "Connected sources" panel with one section, one Sync button, one * stats block per identity. Sync only appears when: * 1. the connection is currently ACTIVE/CONNECTED, AND - * 2. the toolkit is in the syncable allow-list (today: gmail). + * 2. the toolkit is in the syncable allow-list passed by the parent. */ import { useCallback, useEffect, useMemo, useState } from 'react'; diff --git a/app/src/components/intelligence/MemoryWorkspace.tsx b/app/src/components/intelligence/MemoryWorkspace.tsx index 569e958c4..4dc84bb70 100644 --- a/app/src/components/intelligence/MemoryWorkspace.tsx +++ b/app/src/components/intelligence/MemoryWorkspace.tsx @@ -54,11 +54,17 @@ interface MemoryWorkspaceProps { * adding chunks to the memory tree. * * Source of truth: providers under - * `src/openhuman/composio/providers//` that call - * `ingest_page_into_memory_tree`. Today that's gmail. Add a slug here - * when a new provider lands a memory-tree ingest path. + * `src/openhuman/memory_sync/composio/providers//` that + * persist items via `store_skill_sync` into the memory tree. */ -const SYNCABLE_TOOLKITS: ReadonlySet = new Set(['gmail']); +const SYNCABLE_TOOLKITS: ReadonlySet = new Set([ + 'clickup', + 'github', + 'gmail', + 'linear', + 'notion', + 'slack', +]); export function MemoryWorkspace({ onToast }: MemoryWorkspaceProps) { const { t } = useT(); diff --git a/app/src/components/intelligence/__tests__/MemoryWorkspace.test.tsx b/app/src/components/intelligence/__tests__/MemoryWorkspace.test.tsx index b9add6cc1..776259cef 100644 --- a/app/src/components/intelligence/__tests__/MemoryWorkspace.test.tsx +++ b/app/src/components/intelligence/__tests__/MemoryWorkspace.test.tsx @@ -235,24 +235,23 @@ describe('MemoryWorkspace (graph view)', () => { }); }); - it('hides toolkits without a memory-tree ingest provider entirely', async () => { + it('shows sync rows for provider-backed toolkits and hides non-syncable ones', async () => { listConnections.mockResolvedValue({ connections: [ { id: 'conn-gmail', toolkit: 'gmail', status: 'ACTIVE', accountEmail: 'a@x' }, { id: 'conn-slack', toolkit: 'slack', status: 'ACTIVE', workspace: 'acme' }, { id: 'conn-notion', toolkit: 'notion', status: 'ACTIVE' }, + { id: 'conn-discord', toolkit: 'discord', status: 'ACTIVE' }, ], }); renderWithProviders(); - // Gmail row exists with a working Sync button. + // Provider-backed toolkits should render actionable Sync rows expect(await screen.findByTestId('memory-source-sync-gmail')).toBeInTheDocument(); - // Non-syncable toolkits are filtered out completely — neither - // the row nor the Sync button render. Cleaner than a "no sync - // yet" placeholder for an action the user can't take. - expect(screen.queryByTestId('memory-source-row-slack')).toBeNull(); - expect(screen.queryByTestId('memory-source-row-notion')).toBeNull(); - expect(screen.queryByTestId('memory-source-sync-slack')).toBeNull(); - expect(screen.queryByTestId('memory-source-sync-notion')).toBeNull(); + expect(screen.getByTestId('memory-source-sync-slack')).toBeInTheDocument(); + expect(screen.getByTestId('memory-source-sync-notion')).toBeInTheDocument(); + // Non-syncable toolkits stay hidden. + expect(screen.queryByTestId('memory-source-row-discord')).toBeNull(); + expect(screen.queryByTestId('memory-source-sync-discord')).toBeNull(); }); it('toggling to Contacts mode re-fetches the graph with mode=contacts', async () => { diff --git a/src/openhuman/memory_sync/composio/providers/mod.rs b/src/openhuman/memory_sync/composio/providers/mod.rs index e2cb340e2..a9746d60d 100644 --- a/src/openhuman/memory_sync/composio/providers/mod.rs +++ b/src/openhuman/memory_sync/composio/providers/mod.rs @@ -149,8 +149,8 @@ pub fn capability_matrix() -> Vec { /// /// 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. +/// without a full native provider still benefit from curated +/// whitelisting. /// /// Lookup key is the lowercased prefix returned by /// [`toolkit_from_slug`] applied to the action slug — e.g.