From 484e31dc1d34a8ed592e93a1ffd474bec40e239a Mon Sep 17 00:00:00 2001 From: YOMXXX Date: Mon, 25 May 2026 14:24:35 +0800 Subject: [PATCH] feat(memory): clear source memory on disconnect (#2528) Co-authored-by: Steven Enamakel --- app/src/components/channels/DiscordConfig.tsx | 113 +++++++--- .../components/channels/TelegramConfig.tsx | 34 ++- .../channels/__tests__/DiscordConfig.test.tsx | 83 ++++++- .../__tests__/TelegramConfig.test.tsx | 32 ++- .../composio/ComposioConnectModal.test.tsx | 41 ++++ .../composio/ComposioConnectModal.tsx | 24 +- app/src/lib/composio/composioApi.test.ts | 16 ++ app/src/lib/composio/composioApi.ts | 11 +- app/src/lib/composio/types.ts | 1 + app/src/lib/i18n/chunks/ar-1.ts | 3 + app/src/lib/i18n/chunks/bn-1.ts | 3 + app/src/lib/i18n/chunks/de-1.ts | 3 + app/src/lib/i18n/chunks/en-1.ts | 3 + app/src/lib/i18n/chunks/es-1.ts | 3 + app/src/lib/i18n/chunks/fr-1.ts | 3 + app/src/lib/i18n/chunks/hi-1.ts | 3 + app/src/lib/i18n/chunks/id-1.ts | 3 + app/src/lib/i18n/chunks/it-1.ts | 3 + app/src/lib/i18n/chunks/ko-1.ts | 3 + app/src/lib/i18n/chunks/pt-1.ts | 3 + app/src/lib/i18n/chunks/ru-1.ts | 3 + app/src/lib/i18n/chunks/zh-CN-1.ts | 3 + app/src/lib/i18n/en.ts | 3 + .../__tests__/channelConnectionsApi.test.ts | 14 ++ app/src/services/api/channelConnectionsApi.ts | 19 +- src/openhuman/channels/controllers/ops.rs | 22 ++ .../channels/controllers/ops_tests.rs | 75 ++++++- src/openhuman/channels/controllers/schemas.rs | 12 +- .../channels/controllers/schemas_tests.rs | 12 + src/openhuman/composio/ops.rs | 208 +++++++++++++++++- src/openhuman/composio/ops_test.rs | 157 ++++++++++++- src/openhuman/composio/schemas.rs | 47 ++-- src/openhuman/composio/types.rs | 2 + src/openhuman/memory_store/chunks/store.rs | 185 +++++++++++++++- .../memory_store/chunks/store_tests.rs | 145 ++++++++++++ .../memory_sync/composio/providers/profile.rs | 4 + 36 files changed, 1230 insertions(+), 69 deletions(-) diff --git a/app/src/components/channels/DiscordConfig.tsx b/app/src/components/channels/DiscordConfig.tsx index 9e16d4925..06b74fbae 100644 --- a/app/src/components/channels/DiscordConfig.tsx +++ b/app/src/components/channels/DiscordConfig.tsx @@ -46,6 +46,9 @@ const DiscordConfig = ({ definition }: DiscordConfigProps) => { const [busyKeys, setBusyKeys] = useState>({}); const [fieldValues, setFieldValues] = useState>>({}); + const [clearMemoryOnDisconnect, setClearMemoryOnDisconnect] = useState>( + {} + ); const [error, setError] = useState(null); /** Pending link tokens, keyed by compositeKey (discord:managed_dm). Only present while polling. */ const [linkToken, setLinkToken] = useState(null); @@ -259,15 +262,19 @@ const DiscordConfig = ({ definition }: DiscordConfigProps) => { const handleDisconnect = useCallback( (authMode: ChannelAuthMode) => { + const key = `discord:${authMode}`; void runBusy(`discord:${authMode}`, async () => { log('disconnecting discord via %s', authMode); pollAbort.current?.abort(); setLinkToken(null); - await channelConnectionsApi.disconnectChannel('discord', authMode); + await channelConnectionsApi.disconnectChannel('discord', authMode, { + clearMemory: Boolean(clearMemoryOnDisconnect[key]), + }); + setClearMemoryOnDisconnect(prev => ({ ...prev, [key]: false })); dispatch(disconnectChannelConnection({ channel: 'discord', authMode })); }); }, - [dispatch, runBusy] + [clearMemoryOnDisconnect, dispatch, runBusy] ); const copyToken = useCallback(() => { @@ -366,38 +373,86 @@ const DiscordConfig = ({ definition }: DiscordConfigProps) => { {/* Connected state for managed_dm — show only Disconnect */} {spec.mode === 'managed_dm' && status === 'connected' ? ( -
-

- {t('channels.discord.accountLinked')} -

- -
- ) : /* Connect / Disconnect buttons for all other modes and states */ - spec.mode !== 'managed_dm' || status !== 'connecting' ? ( -
- {status !== 'connected' && ( + <> + +
+

+ {t('channels.discord.accountLinked')} +

+
+ + ) : /* Connect / Disconnect buttons for all other modes and states */ + spec.mode !== 'managed_dm' || status !== 'connecting' ? ( + <> + {status === 'connected' && ( + )} - -
+
+ {status !== 'connected' && ( + + )} + +
+ ) : null} {/* Server + Channel picker — shown after successful bot_token connection */} diff --git a/app/src/components/channels/TelegramConfig.tsx b/app/src/components/channels/TelegramConfig.tsx index 10de76184..c022ab14d 100644 --- a/app/src/components/channels/TelegramConfig.tsx +++ b/app/src/components/channels/TelegramConfig.tsx @@ -46,6 +46,9 @@ const TelegramConfig = ({ definition }: TelegramConfigProps) => { const [busyKeys, setBusyKeys] = useState>({}); const [fieldValues, setFieldValues] = useState>>({}); + const [clearMemoryOnDisconnect, setClearMemoryOnDisconnect] = useState>( + {} + ); const [error, setError] = useState(null); const managedDmPollControllers = useRef>({}); @@ -323,11 +326,14 @@ const TelegramConfig = ({ definition }: TelegramConfigProps) => { void runBusy(key, async () => { log('disconnecting telegram via %s', authMode); stopManagedDmPolling(`telegram:${authMode}`); - await channelConnectionsApi.disconnectChannel('telegram', authMode); + await channelConnectionsApi.disconnectChannel('telegram', authMode, { + clearMemory: Boolean(clearMemoryOnDisconnect[key]), + }); + setClearMemoryOnDisconnect(prev => ({ ...prev, [key]: false })); dispatch(disconnectChannelConnection({ channel: 'telegram', authMode })); }); }, - [dispatch, runBusy, stopManagedDmPolling] + [clearMemoryOnDisconnect, dispatch, runBusy, stopManagedDmPolling] ); return ( @@ -397,6 +403,30 @@ const TelegramConfig = ({ definition }: TelegramConfigProps) => { )} + {status === 'connected' && ( + + )} +