feat(agent-memory): add Redis Agent Memory API module - #6424
feat(agent-memory): add Redis Agent Memory API module#6424booleanhunter wants to merge 1 commit into
Conversation
5c289be to
68cbd32
Compare
Code Coverage - Backend unit tests
Test suite run success3795 tests passing in 327 suites. Report generated by 🧪jest coverage report action from d93f849 |
Code Coverage - Integration Tests
|
68cbd32 to
3dc5bc5
Compare
Add a NestJS module that connects RedisInsight to Redis Agent Memory (RAM) stores through the @redis-iris/agent-memory SDK (0.2.0). Endpoints: - CRUD for endpoint connections, credentials encrypted at rest - Verify reachability and credentials on connect - backendType discriminator fixed to Cloud, leaving room for other transports without a schema migration Working memory: - Read a session's message log, running summary, and namespace - Add events (creating the session if needed) - Clear a session Long-term memory: - Semantic + keyword search with a similarity-threshold control, filtered by owner, namespace, session, memory type, and topics - Delete records - Discover the distinct owners and namespaces present in a store Store configuration: - Read the store's general settings and memory TTLs
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3dc5bc5121
ℹ️ 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".
| const data = await this.sdkCall(() => | ||
| this.sdk.searchLongTermMemory({ text: MATCH_ALL_TEXT }), | ||
| ); | ||
| const items = data?.items ?? []; |
There was a problem hiding this comment.
Enumerate all pages when discovering filter values
When a store contains more memories than one search response can return, this scans only the first items page and silently omits owners and namespaces that occur later. The normal search path explicitly uses a bounded limit, while this discovery endpoint exposes no pagination, so its filter options become incomplete; paginate through all results or use a server-side aggregation endpoint.
Useful? React with 👍 / 👎.
| serviceName: store.name ?? store.serviceName ?? this.endpoint.name, | ||
| storeId: store.id ?? this.endpoint.storeId, | ||
| database: store.databaseName ?? store.database ?? store.databaseId, | ||
| endpoint: store.endpoint ?? store.publicEndpoint ?? this.endpoint.url, | ||
| }; |
There was a problem hiding this comment.
Return configured TTL values from the config endpoint
For stores with working- or long-term-memory TTLs configured, GET /agent-memory/:id/config can never return those settings even though the controller advertises “general settings + memory TTLs”: this mapping and AgentMemoryConfiguration contain only identity and endpoint fields. Add the TTL fields to the response contract and populate them, or narrow the documented contract if TTLs are intentionally unavailable.
Useful? React with 👍 / 👎.
| items.map((m) => m.namespace).filter((ns): ns is string => Boolean(ns)), | ||
| ), | ||
| ]; | ||
| return { users, namespaces }; |
There was a problem hiding this comment.
Discovery scan misses most store facets
High Severity
discoverFilters builds distinct owners and namespaces from a single searchLongTermMemory call with only a match-all text and no limit or pagination. That returns one default-sized page, so owners and namespaces that appear only on later pages never show up in discovery.
Reviewed by Cursor Bugbot for commit 3dc5bc5. Configure here.
3dc5bc5 to
d93f849
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d93f849a02
ℹ️ 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".
| async ensureAuth(): Promise<void> { | ||
| // Static bearer token - nothing to refresh. | ||
| } |
There was a problem hiding this comment.
Revalidate cached clients on connect
When a client is already pooled, AgentMemoryClientProvider.getOrCreate() calls this no-op and the /agent-memory/:id/connect endpoint returns 200 without making any request. If the store becomes unavailable or its API key is revoked after the initial connection, repeated connect checks continue reporting success while the pool remains active; perform an authenticated probe for explicit connect requests or revalidate cached clients here.
Useful? React with 👍 / 👎.
| this.sdk.listSessions( | ||
| SESSIONS_LIST_LIMIT, | ||
| undefined, | ||
| filter.userId || undefined, | ||
| filter.userId ? undefined : true, |
There was a problem hiding this comment.
Return every session from the listing endpoint
For stores containing more than 50 sessions, this request always returns only the first page because the SDK offset argument is left undefined and the controller exposes no pagination parameters. Consequently, later sessions cannot be discovered or opened through this API; iterate through the SDK pages or expose pagination in the REST contract.
Useful? React with 👍 / 👎.
| @UsePipes( | ||
| new ValidationPipe({ | ||
| transform: true, | ||
| transformOptions: { groups: ['security'] }, | ||
| }), |
There was a problem hiding this comment.
Strip undeclared fields from endpoint DTOs
Because this ValidationPipe does not enable whitelist, undeclared properties survive transformation even though the DTO uses OmitType. A request such as PATCH /agent-memory/A with an id field therefore reaches deepMerge, replaces the loaded model's primary key, and can make the repository save data under a different endpoint ID instead of updating A; enable whitelisting or explicitly reject non-DTO fields.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 2 potential issues.
There are 3 total unresolved issues (including 1 from previous review).
❌ 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 d93f849. Configure here.
| ), | ||
| ); | ||
| return (data?.items ?? []).filter((id): id is string => Boolean(id)); | ||
| } |
There was a problem hiding this comment.
Session list silently truncates after fifty
Medium Severity
listSessions always requests SESSIONS_LIST_LIMIT (50) and never follows pagination, so GET /agent-memory/:id/sessions cannot return more than the first page of session ids even when the store has more.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit d93f849. Configure here.
| }), | ||
| ); | ||
| const items = (data?.items ?? []).map(fromCloudMemory); | ||
| return { memories: items, total: items.length }; |
There was a problem hiding this comment.
Search total reflects page size only
Medium Severity
Long-term search always passes limit: 50 and sets total to the returned page length, with no pageToken handling. Clients treating total as the store hit count will under-count matches and cannot fetch further pages.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit d93f849. Configure here.


Add a NestJS module that connects RedisInsight to Redis Agent Memory (RAM) stores through the @redis-iris/agent-memory SDK (0.2.0).
Endpoints:
Working memory:
Long-term memory:
Store configuration:
Note
Medium Risk
New surface area stores bearer API keys (encrypted) and proxies destructive memory operations to external RAM stores; mitigations include connectivity checks, security-group serialization, and pooled client invalidation on credential changes.
Overview
Adds a NestJS Agent Memory module wired into
AppModule, backed by SQLite (agent_memory_endpointmigration + TypeORM entity) and the@redis-iris/agent-memorySDK.Connection management: REST CRUD for saved RAM store connections (URL, store id, cloud
backendType), with API keys encrypted at rest and omitted from list responses; create/update probe connectivity before save, and pooled per-session clients are evicted when connection fields change. AGET …/connectroute verifies reachability.Data plane (proxied through the backend so credentials stay server-side): routes under
agent-memory/:idfor working memory (list sessions, read/clear session log + summary, append messages), long-term memory (hybrid search with filters/threshold, bulk delete), discovery of distinct users/namespaces, and store config readout. The Cloud client normalizes Iris responses and maps axios/SDK errors to HTTP exceptions.Also adds
.playwright-cli/to.gitignore.Reviewed by Cursor Bugbot for commit d93f849. Bugbot is set up for automated code reviews on this repo. Configure here.