-
Notifications
You must be signed in to change notification settings - Fork 187
Fix several bugs on agentic memory #4476
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
WalkthroughReplaced null/empty memory index mappings with a safe default and added a new initIndexWithContext path; also guarded admin-role checks with a user nullity check in memory container search action. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (2)
ml-algorithms/src/main/java/org/opensearch/ml/engine/indices/MLIndicesHandler.java (2)
175-200: Memory index defaults align with PR goal; consider de-duplicating and caching lookupsUsing
ALL_NODES_REPLICA_INDEX_SETTINGSwhenconfiguration.getMemoryIndexMapping(...)isnullor empty for session, working, and long‑term history indices matches the intent to have safe multi‑node defaults and avoids relying oninitIndexIfAbsent’s generic fallback.Two small, optional cleanups:
- Cache the result of
configuration.getMemoryIndexMapping(...)in a local variable per method to avoid calling it twice and to make the null/empty handling clearer.- The three methods now share essentially the same pattern; consider a small helper (e.g.,
resolveMemoryIndexSettings(MemoryConfiguration config, String logicalIndex)) to centralize this logic and reduce future drift between indices.These are non-blocking and can be done later if you prefer to keep this PR minimal.
277-282: Long‑term memory index: new replica default looks correct; verify config access patternAdding
ALL_NODES_REPLICA_INDEX_SETTINGSin theelsebranch ensures long‑term memory indices get a sane default when no per‑index settings are configured, which is consistent with the other memory indices and should help with multi‑node index creation.One thing to double‑check:
- The guard uses
memoryConfig.getIndexSettings().containsKey(LONG_TERM_MEMORY_INDEX)but then pulls the map viamemoryConfig.getMemoryIndexMapping(LONG_TERM_MEMORY_INDEX). If these two accessors are backed by the same underlying structure, this is fine; if not, there’s a small risk of divergence (e.g., the key present in one but not the other). A slightly clearer pattern would be to retrieve the map once and check fornull/isEmpty()directly, similar to the other memory index methods.Functionally this looks good; I’d just confirm the
MemoryConfigurationAPI contract or simplify it in a follow‑up.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
ml-algorithms/src/main/java/org/opensearch/ml/engine/indices/MLIndicesHandler.java(2 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: Build and Test MLCommons Plugin on linux (21)
- GitHub Check: Build and Test MLCommons Plugin on Windows (21)
- GitHub Check: Build and Test MLCommons Plugin on Windows (24)
- GitHub Check: Build and Test MLCommons Plugin on linux (24)
Signed-off-by: Sicheng Song <sicheng.song@outlook.com>
…#4407) Signed-off-by: Dhrubo Saha <dhrubo@amazon.com>
01e0c40 to
fcace1b
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (3)
plugin/src/main/java/org/opensearch/ml/action/memorycontainer/TransportSearchMemoryContainerAction.java (1)
91-94: Null-guard onusercorrectly prevents potential NPEThe updated condition
if (user != null && !memoryContainerHelper.isAdminUser(user))safely avoids callingisAdminUserandaddUserBackendRolesFilterwith a nullUser, eliminating a possible NPE while preserving intended behavior (filter only for non-admin, non-null users). If helpful for future readers, consider a brief comment clarifying what anulluser represents here (e.g., system or security-disabled context) and why no filter is applied in that case.ml-algorithms/src/main/java/org/opensearch/ml/engine/indices/MLIndicesHandler.java (2)
289-295: Default long‑term memory index settings behavior looks good; consider future upgrade storyUsing
ALL_NODES_REPLICA_INDEX_SETTINGSas a fallback whenLONG_TERM_MEMORY_INDEXhas no explicit settings is consistent with the other memory indices and should help with multi‑node robustness. The conditional routing toinitIndexIfAbsent(system index) vsinitIndexWithContext(non‑system) also makes sense.One thing to be aware of: the non‑system path via
initIndexWithContextdoes not perform any mapping/version checks or settings updates if the index already exists, unlikeinitIndexIfAbsent. If you ever need schema upgrades for non‑system long‑term memory indices, you’ll likely need a follow‑up to add an upgrade path similar to the system index flow.Also applies to: 298-302
318-351:initIndexWithContextbehavior differences and unusedversionparameterThe new
initIndexWithContextmethod cleanly handles parallel index creation and applies a default viaObjects.requireNonNullElse(indexSettings, DEFAULT_INDEX_SETTINGS), which matches the use cases in this PR.Two minor points to consider:
- The
versionargument is currently unused; keeping it in the signature may be confusing sinceinitIndexIfAbsentusesversionto drive upgrade logic. Either document that it’s intentionally unused here or remove it if you don’t expect upgrades on this path.- Unlike
initIndexIfAbsent, this method does not checkdoesMultiTenantIndexExistand does not perform mapping/settings upgrades for existing indices. That seems intentional for context‑specific/non‑system indices, but it’s worth making sure all call sites understand this semantic difference.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
ml-algorithms/src/main/java/org/opensearch/ml/engine/indices/MLIndicesHandler.java(4 hunks)plugin/src/main/java/org/opensearch/ml/action/memorycontainer/TransportSearchMemoryContainerAction.java(1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: spotless
| public void createSessionMemoryDataIndex(String indexName, MemoryConfiguration configuration, ActionListener<Boolean> listener) { | ||
| String indexMappings = getMapping(ML_MEMORY_SESSION_INDEX_MAPPING_PATH); | ||
| Map<String, Object> indexSettings = configuration.getMemoryIndexMapping(SESSION_INDEX); | ||
| initIndexIfAbsent(indexName, StringUtils.toJson(indexMappings), indexSettings, 1, listener); | ||
| Map<String, Object> indexSettings = configuration.getMemoryIndexMapping(SESSION_INDEX) == null | ||
| || configuration.getMemoryIndexMapping(SESSION_INDEX).isEmpty() | ||
| ? ALL_NODES_REPLICA_INDEX_SETTINGS | ||
| : configuration.getMemoryIndexMapping(SESSION_INDEX); | ||
| if (configuration.isUseSystemIndex()) { | ||
| initIndexIfAbsent(indexName, StringUtils.toJson(indexMappings), indexSettings, 1, listener); | ||
| } else { | ||
| initIndexWithContext(indexName, StringUtils.toJson(indexMappings), indexSettings, 1, listener); | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Avoid double-encoding mapping JSON in memory index creators
getMapping(...) already returns a JSON string for the mapping. Wrapping that string with StringUtils.toJson(indexMappings) will typically serialize it again as a JSON string literal (e.g., "\"{...}\""), which will not be a valid mapping document when passed to CreateIndexRequest.mapping(..., XContentType.JSON). That would cause index creation to fail for session, working, and long-term memory history indices.
At the same time, the new defaulting to ALL_NODES_REPLICA_INDEX_SETTINGS when getMemoryIndexMapping(...) is null/empty looks correct and aligned with the PR’s goal.
Suggested fix (applies to all three methods):
- if (configuration.isUseSystemIndex()) {
- initIndexIfAbsent(indexName, StringUtils.toJson(indexMappings), indexSettings, 1, listener);
- } else {
- initIndexWithContext(indexName, StringUtils.toJson(indexMappings), indexSettings, 1, listener);
- }
+ if (configuration.isUseSystemIndex()) {
+ initIndexIfAbsent(indexName, indexMappings, indexSettings, 1, listener);
+ } else {
+ initIndexWithContext(indexName, indexMappings, indexSettings, 1, listener);
+ }Also applies to: 189-200, 202-213
🤖 Prompt for AI Agents
In
ml-algorithms/src/main/java/org/opensearch/ml/engine/indices/MLIndicesHandler.java
around lines 176-187 (and similarly apply to 189-200 and 202-213), the code
double-encodes the mapping JSON by calling StringUtils.toJson(indexMappings)
even though getMapping(...) already returns a JSON string; remove the
StringUtils.toJson(...) wrapper and pass the indexMappings string directly to
initIndexIfAbsent/initIndexWithContext so the mapping is provided as raw JSON
(ensure the calls still use the JSON content type where required).
|
| .wrap(wrappedListener::onResponse, e -> wrapListenerToHandleSearchIndexNotFound(e, wrappedListener)); | ||
|
|
||
| if (!memoryContainerHelper.isAdminUser(user)) { | ||
| if (user != null && !memoryContainerHelper.isAdminUser(user)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what happens for security disabled cluster.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All user will have admin permission then
Will add UTs |
Description
Related Issues
Resolves #[Issue number to be closed when this PR is merged]
Check List
--signoff.By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
For more information on following Developer Certificate of Origin and signing off your commits, please check here.
Summary by CodeRabbit
✏️ Tip: You can customize this high-level summary in your review settings.