Skip to content

feat(agent-memory): add Redis Agent Memory API module - #6424

Open
booleanhunter wants to merge 1 commit into
mainfrom
feature/agent-memory-inspector-api
Open

feat(agent-memory): add Redis Agent Memory API module#6424
booleanhunter wants to merge 1 commit into
mainfrom
feature/agent-memory-inspector-api

Conversation

@booleanhunter

@booleanhunter booleanhunter commented Aug 19, 2026

Copy link
Copy Markdown
Collaborator

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

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_endpoint migration + TypeORM entity) and the @redis-iris/agent-memory SDK.

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. A GET …/connect route verifies reachability.

Data plane (proxied through the backend so credentials stay server-side): routes under agent-memory/:id for 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.

@booleanhunter
booleanhunter force-pushed the feature/agent-memory-inspector-api branch from 5c289be to 68cbd32 Compare August 19, 2026 12:09
@github-actions

github-actions Bot commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

Code Coverage - Backend unit tests

St.
Category Percentage Covered / Total
🟢 Statements 93.13% 16683/17913
🟡 Branches 75.08% 5534/7371
🟢 Functions 87.55% 2560/2924
🟢 Lines 93% 15950/17151

Test suite run success

3795 tests passing in 327 suites.

Report generated by 🧪jest coverage report action from d93f849

@github-actions

github-actions Bot commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

Code Coverage - Integration Tests

Status Category Percentage Covered / Total
🟡 Statements 79.13% 18703/23634
🟡 Branches 60.3% 8746/14504
🟡 Functions 66.17% 2520/3808
🟡 Lines 78.78% 17608/22350

@booleanhunter
booleanhunter force-pushed the feature/agent-memory-inspector-api branch from 68cbd32 to 3dc5bc5 Compare August 19, 2026 14:45
@booleanhunter
booleanhunter marked this pull request as ready for review August 19, 2026 15:55
@booleanhunter
booleanhunter requested a review from a team as a code owner August 19, 2026 15:55
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

@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: 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".

Comment on lines +207 to +210
const data = await this.sdkCall(() =>
this.sdk.searchLongTermMemory({ text: MATCH_ALL_TEXT }),
);
const items = data?.items ?? [];

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 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 👍 / 👎.

Comment on lines +239 to +243
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,
};

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 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 };

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 3dc5bc5. Configure here.

@booleanhunter
booleanhunter force-pushed the feature/agent-memory-inspector-api branch from 3dc5bc5 to d93f849 Compare August 19, 2026 16:04

@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: 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".

Comment on lines +99 to +101
async ensureAuth(): Promise<void> {
// Static bearer token - nothing to refresh.
}

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 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 👍 / 👎.

Comment on lines +106 to +110
this.sdk.listSessions(
SESSIONS_LIST_LIMIT,
undefined,
filter.userId || undefined,
filter.userId ? undefined : true,

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 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 👍 / 👎.

Comment on lines +35 to +39
@UsePipes(
new ValidationPipe({
transform: true,
transformOptions: { groups: ['security'] },
}),

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 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 👍 / 👎.

@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 2 potential issues.

There are 3 total unresolved issues (including 1 from previous review).

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 d93f849. Configure here.

),
);
return (data?.items ?? []).filter((id): id is string => Boolean(id));
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit d93f849. Configure here.

}),
);
const items = (data?.items ?? []).map(fromCloudMemory);
return { memories: items, total: items.length };

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit d93f849. Configure here.

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.

1 participant