Skip to content

Commit 7eb18a9

Browse files
committed
Allow context management inline create in register agent without storing in index (#4403)
* allow inline create context management without storing in agent register Signed-off-by: Mingshi Liu <mingshl@amazon.com> * make ML_COMMONS_MULTI_TENANCY_ENABLED default is false Signed-off-by: Mingshi Liu <mingshl@amazon.com> --------- Signed-off-by: Mingshi Liu <mingshl@amazon.com>
1 parent 767e1d7 commit 7eb18a9

File tree

6 files changed

+74
-4
lines changed

6 files changed

+74
-4
lines changed

common/src/main/java/org/opensearch/ml/common/agent/MLAgent.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,14 @@ public boolean hasContextManagementTemplate() {
464464
return contextManagementName != null;
465465
}
466466

467+
/**
468+
* Check if this agent has inline context management configuration
469+
* @return true if agent has inline context management configuration
470+
*/
471+
public boolean hasInlineContextManagement() {
472+
return contextManagement != null;
473+
}
474+
467475
/**
468476
* Get the context management template name if this agent references one
469477
* @return the template name, or null if no template reference

common/src/main/java/org/opensearch/ml/common/contextmanager/ContextManagerHookProvider.java

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,16 @@ public ContextManagerHookProvider(List<ContextManager> contextManagers) {
4747
*/
4848
@Override
4949
public void registerHooks(HookRegistry registry) {
50-
// Register callbacks for each hook type
51-
registry.addCallback(PreLLMEvent.class, this::handlePreLLM);
52-
registry.addCallback(EnhancedPostToolEvent.class, this::handlePostTool);
53-
registry.addCallback(PostMemoryEvent.class, this::handlePostMemory);
50+
// Only register callbacks for hooks that have managers configured
51+
if (hookToManagersMap.containsKey("PRE_LLM")) {
52+
registry.addCallback(PreLLMEvent.class, this::handlePreLLM);
53+
}
54+
if (hookToManagersMap.containsKey("POST_TOOL")) {
55+
registry.addCallback(EnhancedPostToolEvent.class, this::handlePostTool);
56+
}
57+
if (hookToManagersMap.containsKey("POST_MEMORY")) {
58+
registry.addCallback(PostMemoryEvent.class, this::handlePostMemory);
59+
}
5460

5561
log.info("Registered context manager hooks for {} managers", contextManagers.size());
5662
}

ml-algorithms/src/main/java/org/opensearch/ml/engine/algorithms/agent/MLAgentExecutor.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -484,6 +484,20 @@ private void processContextManagement(MLAgent mlAgent, HookRegistry hookRegistry
484484
return; // Runtime parameter takes precedence, let MLExecuteTaskRunner handle it
485485
}
486486

487+
// Check if already processed to avoid duplicate registrations
488+
if ("true".equals(inputDataSet.getParameters().get("context_management_processed"))) {
489+
log.debug("Context management already processed for this execution, skipping");
490+
return;
491+
}
492+
493+
// Check if HookRegistry already has callbacks (from previous runtime setup)
494+
// Don't override with inline configuration if runtime config is already active
495+
if (hookRegistry.getCallbackCount(org.opensearch.ml.common.hooks.EnhancedPostToolEvent.class) > 0
496+
|| hookRegistry.getCallbackCount(org.opensearch.ml.common.hooks.PreLLMEvent.class) > 0) {
497+
log.info("HookRegistry already has active configuration, skipping inline context management");
498+
return;
499+
}
500+
487501
ContextManagementTemplate template = null;
488502
String templateName = null;
489503

ml-algorithms/src/main/java/org/opensearch/ml/engine/algorithms/agent/MLPlanExecuteAndReflectAgentRunner.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -484,6 +484,7 @@ private void executePlanningLoop(
484484
.build();
485485

486486
// Pass hookRegistry to internal agent execution
487+
// TODO need to check if the agentInput already have the hookResgistry?
487488
agentInput.setHookRegistry(hookRegistry);
488489

489490
MLExecuteTaskRequest executeRequest = new MLExecuteTaskRequest(FunctionName.AGENT, agentInput);

ml-algorithms/src/test/java/org/opensearch/ml/engine/algorithms/agent/MLAgentExecutorTest.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,4 +301,21 @@ private MLAgent createTestAgent(String type) {
301301
.appType("test-app")
302302
.build();
303303
}
304+
305+
@Test
306+
public void testContextManagementProcessedFlagPreventsReprocessing() {
307+
// Test that the context_management_processed flag prevents duplicate processing
308+
Map<String, String> parameters = new HashMap<>();
309+
310+
// First check - should allow processing
311+
boolean shouldProcess1 = !"true".equals(parameters.get("context_management_processed"));
312+
assertTrue("First call should allow processing", shouldProcess1);
313+
314+
// Mark as processed (simulating what the method does)
315+
parameters.put("context_management_processed", "true");
316+
317+
// Second check - should prevent processing
318+
boolean shouldProcess2 = !"true".equals(parameters.get("context_management_processed"));
319+
assertFalse("Second call should prevent processing", shouldProcess2);
320+
}
304321
}

plugin/src/test/java/org/opensearch/ml/action/contextmanagement/ContextManagerFactoryTests.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,4 +140,28 @@ public void testCreateContextManager_EmptyType() {
140140
assertTrue(e.getMessage().contains("Unsupported context manager type"));
141141
}
142142
}
143+
144+
@Test
145+
public void testContextManagerHookProvider_SelectiveRegistration() {
146+
// Test that ContextManagerHookProvider only registers hooks for configured managers
147+
java.util.Map<String, java.util.List<String>> hookToManagersMap = new java.util.HashMap<>();
148+
149+
// Test 1: Only POST_TOOL configured
150+
hookToManagersMap.put("POST_TOOL", java.util.Arrays.asList("ToolsOutputTruncateManager"));
151+
152+
// Simulate the registration logic
153+
java.util.Set<String> registeredHooks = new java.util.HashSet<>();
154+
if (hookToManagersMap.containsKey("PRE_LLM")) {
155+
registeredHooks.add("PRE_LLM");
156+
}
157+
if (hookToManagersMap.containsKey("POST_TOOL")) {
158+
registeredHooks.add("POST_TOOL");
159+
}
160+
if (hookToManagersMap.containsKey("POST_MEMORY")) {
161+
registeredHooks.add("POST_MEMORY");
162+
}
163+
164+
// Assert only POST_TOOL is registered
165+
assertTrue("Should only register POST_TOOL hook", registeredHooks.size() == 1 && registeredHooks.contains("POST_TOOL"));
166+
}
143167
}

0 commit comments

Comments
 (0)