Skip to content

feat(agent-memory): add long-term memory explorer tab - #6429

Open
booleanhunter wants to merge 1 commit into
feature/agent-memory-inspector-overviewfrom
feature/agent-memory-inspector-ltm
Open

feat(agent-memory): add long-term memory explorer tab#6429
booleanhunter wants to merge 1 commit into
feature/agent-memory-inspector-overviewfrom
feature/agent-memory-inspector-ltm

Conversation

@booleanhunter

@booleanhunter booleanhunter commented Aug 19, 2026

Copy link
Copy Markdown
Collaborator

Add the Long-term memory tab to the Agent Memory workspace: a searchable records explorer.

Memory records pane:

  • Semantic + keyword search with a minimum-similarity control
  • Filter by owner, namespace, session, memory type, and topic, with active filters shown as removable pills
  • Record cards: type badge, created/updated time, id, text, topic chips, and source session
  • Copy a record's id or session id
  • Click a topic or session on a card to filter by it
Redis Agent Memory - Long Term Memory screen

@github-actions

github-actions Bot commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

Code Coverage - Frontend unit tests

St.
Category Percentage Covered / Total
🟢 Statements 82.9% 29313/35358
🟡 Branches 69.2% 12442/17979
🟡 Functions 78.08% 7820/10016
🟢 Lines 83.39% 28494/34169

Test suite run success

8154 tests passing in 888 suites.

Report generated by 🧪jest coverage report action from 6c70467

@booleanhunter
booleanhunter force-pushed the feature/agent-memory-inspector-ltm branch from c9b5da6 to 118ce70 Compare August 19, 2026 16:05
@booleanhunter
booleanhunter marked this pull request as ready for review August 19, 2026 16:30
@booleanhunter
booleanhunter requested a review from a team as a code owner August 19, 2026 16:30

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 118ce709cf

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +164 to +165
if (isLtmTab) {
dispatch(fetchLongTermMemoryAction(endpointId))

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Fetch explorer data during initial tab load

When the workspace is opened or reloaded directly on the Long-term memory URL, didMountRef makes this effect skip its first run, while bootstrap() only calls refreshAll(), which fetches long-term memory with scopeToSession=true. The explorer therefore initially shows records from the auto-selected Overview session rather than the explorer result set, and remains incomplete until the user manually refreshes or changes a filter; make the bootstrap request depend on the active tab or allow the initial explorer fetch.

Useful? React with 👍 / 👎.

Comment on lines +200 to +202
if (!searchDidMountRef.current) {
searchDidMountRef.current = true
return

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Do not discard the first debounced search

If the user types or pastes within the first 300 ms after this component mounts, the dependency change cancels the initial timer, so the callback for the user's query is the first callback to run; this branch then treats it as the mount callback and returns without issuing a search. The entered query remains displayed while the results are not refreshed until the search changes again, so initialize the mount flag independently of the debounced callback.

Useful? React with 👍 / 👎.

Comment on lines +204 to +205
if (!isConnected) return
dispatch(fetchLongTermMemoryAction(endpointId))

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Cancel explorer searches when leaving the tab

When a user changes the search and switches to Overview before the 300 ms debounce expires, this callback remains scheduled because activeTab is neither a dependency nor a guard. It starts an unscoped explorer request after the tab-switch effect starts the session-scoped Overview request; the thunk's monotonic request sequence makes this later request authoritative, so the Overview pane is populated with explorer results. Cancel or suppress the callback whenever the Long-term memory tab is no longer active.

Useful? React with 👍 / 👎.

@booleanhunter

booleanhunter commented Aug 21, 2026

Copy link
Copy Markdown
Collaborator Author

For feature request GH-6226

@booleanhunter
booleanhunter force-pushed the feature/agent-memory-inspector-ltm branch from 118ce70 to 36f241a Compare August 23, 2026 11:43

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 36f241ac6a

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

/>
<FilterDropdown
label="sessions"
options={sessions}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Populate the explorer with sessions from every owner

When an endpoint has multiple owners, this list contains only the sessions fetched for the auto-selected Overview owner: discoverFiltersAction calls the sessions endpoint with filters.userId, while selecting an owner here only updates longTermMemory.userIds. As a result, the independent explorer cannot select sessions belonging to any other owner, even after that owner is selected in this toolbar; load independent/all session options for the explorer instead of reusing the Overview-scoped list.

Useful? React with 👍 / 👎.

try {
const body: Record<string, unknown> = {
text: longTermMemory.search,
similarityThreshold: longTermMemory.similarityThreshold ?? undefined,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Keep the explorer threshold out of Overview requests

After setting a minimum similarity in the Long-term memory tab and returning to Overview, fetchOverviewLongTermMemoryAction calls this same helper with useSharedScope=true, but the new threshold is still serialized unconditionally. The supposedly owner/session-scoped Overview query is therefore narrowed by a hidden explorer setting and can omit records until the user returns to the explorer and clears it; only include this parameter for explorer requests.

Useful? React with 👍 / 👎.

Comment thread redisinsight/ui/src/slices/agentMemory/thunks/long-term-memory.ts
}
const value = Math.min(1, Math.max(0, Number(raw)))
dispatch(setSimilarityThreshold(Number.isNaN(value) ? null : value))
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Threshold input swallows decimals

Medium Severity

handleThresholdChange immediately stores Number(raw) while the controlled input binds value={similarityThreshold ?? ''}. Intermediate values like a trailing decimal become "" or lose the ., so typing a value such as 0.5 is unreliable for the min-similarity control.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 36f241a. Configure here.

@booleanhunter
booleanhunter force-pushed the feature/agent-memory-inspector-ltm branch from 36f241a to d4289ef Compare August 24, 2026 01:39

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d4289efa38

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +182 to +183
if (!didMountRef.current || !isConnected) return
dispatch(fetchLongTermMemoryAction(endpointId))

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Gate explorer filter refetches to the explorer tab

On a normal initial Overview load, discoverFiltersAction eventually dispatches loadSessionsSuccess, which replaces longTermMemory.sessionIds with a new array; because didMountRef is already true and this effect is not gated by isLtmTab, it starts an unscoped explorer request after the bootstrap/session-scoped requests. The monotonic long-term request sequence makes that request authoritative, so Overview can display records from every owner/session instead of its selected scope.

Useful? React with 👍 / 👎.

Comment on lines +165 to +169
const handleDelete = (memory: LongTermMemoryRecord) => {
dispatch(
deleteLongTermMemoryAction(endpointId, memory.id, () =>
setDeletingId(''),
),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Keep post-delete refetches on the active tab

If a user confirms a deletion and switches to Overview before the DELETE resolves, this action's success path unconditionally starts fetchLongTermMemoryAction, an unscoped explorer request. Because it starts after the tab-switch Overview request, it wins the shared request sequence and replaces the Overview pane with explorer results; the completion refetch needs to respect the current tab or use separate result state.

Useful? React with 👍 / 👎.

},
{
value: AgentMemoryWorkspaceTab.LongTermMemory,
label: 'Long-term memory',

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Translate the new explorer copy

When the UI is displayed in a non-English locale, this new tab label—and the newly added toolbar, card, tooltip, empty-state, and deletion copy—bypasses i18next and remains English. Add agent-memory keys to both locale files and render this copy through useTranslation, as required by the repository's i18n guidance.

AGENTS.md reference: AGENTS.md:L127-L127

Useful? React with 👍 / 👎.

}
const value = Math.min(1, Math.max(0, Number(raw)))
dispatch(setSimilarityThreshold(Number.isNaN(value) ? null : value))
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Threshold applied without search text

Medium Severity

similarityThreshold is sent on every long-term search whenever it is set, including when search is empty. With no other filters the API falls back to match-all text, so a min-similarity value used while browsing can heavily filter or empty the records list even though no semantic query was entered.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit d4289ef. Configure here.

@booleanhunter
booleanhunter force-pushed the feature/agent-memory-inspector-ltm branch from d4289ef to 0c454b2 Compare August 24, 2026 01:57

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0c454b2522

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +56 to +59
...data
.map((m) => m.sessionId)
.filter((id): id is string => Boolean(id)),
...sessionIds,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve unselected sessions after applying a filter

When a user selects one session, the refetch returns records only for that selected session, so rebuilding sessionOptions from data plus sessionIds removes every unselected session from the dropdown. This makes the checkbox-based multi-select unable to add a second session, even though the request supports multiple session IDs; preserve the initially discovered result options or load them independently of the filtered result set.

Useful? React with 👍 / 👎.

Add the Long-term memory tab to the Agent Memory workspace: a searchable
records explorer.

Memory records pane:
- Semantic + keyword search with a minimum-similarity control
- Filter by owner, namespace, session, memory type, and topic, with
  active filters shown as removable pills
- Record cards: type badge, created/updated time, id, text,
  topic chips, and source session
- Copy a record's id or session id
- Click a topic or session on a card to filter by it
@booleanhunter
booleanhunter force-pushed the feature/agent-memory-inspector-ltm branch from 0c454b2 to 6c70467 Compare August 24, 2026 08:18
@booleanhunter booleanhunter self-assigned this Aug 24, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6c7046793f

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +659 to +663
export const ThresholdControl = styled.div`
display: inline-flex;
align-items: center;
gap: 6px;
flex-shrink: 0;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Replace the flex div with a layout component

The new threshold control implements a flex container with styled.div and hardcodes its alignment and gap, bypassing the shared layout system. Use Row or FlexGroup and pass align and gap at the JSX call site so this control follows the repository's layout and spacing conventions.

AGENTS.md reference: AGENTS.md:L154-L155

Useful? React with 👍 / 👎.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

There are 3 total unresolved issues (including 2 from previous reviews).

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 6c70467. Configure here.

</S.CardFooter>
)}
</S.Card>
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Record delete action missing

Medium Severity

MemoryCard never wires delete even though the PR describes deleting a record, deleteLongTermMemoryAction is exported, and CardDeleteWrapper is styled and re-exported for a hover delete control. Users on the Long-term memory tab cannot remove records from the UI.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 6c70467. Configure here.

@booleanhunter booleanhunter linked an issue Aug 24, 2026 that may be closed by this pull request
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.

[Feature Request]: Agent Memory Explorer

1 participant