Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -89,17 +89,17 @@ public SessionListResponse listSessions() throws MemoryClientException {
* Get working memory for a session.
*
* @param sessionId The session ID to retrieve working memory for
* @param userId The user ID to retrieve working memory for
* @param namespace Optional namespace for the session
* @param userId The user ID to retrieve working memory for
* @param modelName Optional model name to determine context window size
* @param contextWindowMax Optional direct specification of context window tokens
* @return WorkingMemoryResponse containing messages, context and metadata
* @throws MemoryClientException if the request fails
*/
public WorkingMemoryResponse getWorkingMemory(
@NotNull String sessionId,
@Nullable String userId,
@Nullable String namespace,
@Nullable String userId,
@Nullable String modelName,
@Nullable Integer contextWindowMax
) throws MemoryClientException {
Expand Down Expand Up @@ -160,8 +160,8 @@ public WorkingMemoryResponse getWorkingMemory(@NotNull String sessionId) throws
*
* @param sessionId The session ID
* @param memory The working memory to store
* @param userId Optional user ID
* @param namespace Optional namespace
* @param userId Optional user ID
* @param modelName Optional model name
* @param contextWindowMax Optional context window max
* @return WorkingMemoryResponse with the stored memory
Expand All @@ -170,8 +170,8 @@ public WorkingMemoryResponse getWorkingMemory(@NotNull String sessionId) throws
public WorkingMemoryResponse putWorkingMemory(
@NotNull String sessionId,
@NotNull WorkingMemory memory,
@Nullable String userId,
@Nullable String namespace,
@Nullable String userId,
@Nullable String modelName,
@Nullable Integer contextWindowMax
) throws MemoryClientException {
Expand Down Expand Up @@ -238,15 +238,15 @@ public WorkingMemoryResponse putWorkingMemory(
* Delete working memory for a session.
*
* @param sessionId The session ID to delete
* @param userId Optional user ID
* @param namespace Optional namespace
* @param userId Optional user ID
* @return AckResponse indicating success
* @throws MemoryClientException if the request fails
*/
public AckResponse deleteWorkingMemory(
@NotNull String sessionId,
@Nullable String userId,
@Nullable String namespace
@Nullable String namespace,
@Nullable String userId
) throws MemoryClientException {
HttpUrl.Builder urlBuilder = HttpUrl.parse(
baseUrl + "/v1/working-memory/" + sessionId
Expand Down Expand Up @@ -309,7 +309,7 @@ public WorkingMemoryResult getOrCreateWorkingMemory(
@Nullable MemoryStrategyConfig longTermMemoryStrategy) throws MemoryClientException {
try {
// Try to get existing memory
WorkingMemoryResponse existing = getWorkingMemory(sessionId, userId, namespace, modelName, contextWindowMax);
WorkingMemoryResponse existing = getWorkingMemory(sessionId, namespace, userId, modelName, contextWindowMax);
return new WorkingMemoryResult(false, existing);
} catch (MemoryNotFoundException e) {
// Memory doesn't exist, create it
Expand All @@ -323,7 +323,7 @@ public WorkingMemoryResult getOrCreateWorkingMemory(
.longTermMemoryStrategy(longTermMemoryStrategy != null ? longTermMemoryStrategy : MemoryStrategyConfig.builder().build())
.build();

WorkingMemoryResponse created = putWorkingMemory(sessionId, emptyMemory, userId, namespace, modelName, contextWindowMax);
WorkingMemoryResponse created = putWorkingMemory(sessionId, emptyMemory, namespace, userId, modelName, contextWindowMax);
return new WorkingMemoryResult(true, created);
}
}
Expand Down Expand Up @@ -368,7 +368,7 @@ public WorkingMemoryResponse setWorkingMemoryData(
.longTermMemoryStrategy(existing.getLongTermMemoryStrategy())
.build();

return putWorkingMemory(sessionId, updated, userId, namespace, null, null);
return putWorkingMemory(sessionId, updated, namespace, userId, null, null);
Copy link

Choose a reason for hiding this comment

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

Swapped namespace and userId in addMemoriesToWorkingMemory call

High Severity

In addMemoriesToWorkingMemory, the call putWorkingMemory(sessionId, updated, null, namespace, null, null) passes null as the namespace parameter and the local namespace variable as the userId parameter. After the signature reorder to (sessionId, memory, namespace, userId, ...), this call was not updated and now has the arguments swapped. The namespace value gets sent as a user_id query parameter and namespace falls back to the default instead of the intended value.

Fix in Cursor Fix in Web

Copy link
Collaborator

Choose a reason for hiding this comment

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

@raphaeldelio 👆🏽

}

/**
Expand Down Expand Up @@ -508,7 +508,7 @@ public WorkingMemoryResponse updateWorkingMemoryData(
.longTermMemoryStrategy(existing.getLongTermMemoryStrategy())
.build();

return putWorkingMemory(sessionId, updated, userId, namespace, null, null);
return putWorkingMemory(sessionId, updated, namespace, userId, null, null);
}

/**
Expand Down Expand Up @@ -553,7 +553,7 @@ public WorkingMemoryResponse appendMessagesToWorkingMemory(
.longTermMemoryStrategy(existing.getLongTermMemoryStrategy())
.build();

return putWorkingMemory(sessionId, updated, userId, namespace, modelName, contextWindowMax);
return putWorkingMemory(sessionId, updated, namespace, userId, modelName, contextWindowMax);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ void testCreateAndRetrieveWorkingMemory() throws Exception {
Thread.sleep(100);

// Retrieve working memory
// Note: getWorkingMemory signature is (sessionId, namespace, userId, modelName, contextWindowMax)
WorkingMemoryResponse getResponse = client.workingMemory()
.getWorkingMemory(sessionId, namespace, null, null, null);

Expand Down Expand Up @@ -298,4 +299,69 @@ void testUpdateWorkingMemoryData() throws Exception {
assertEquals("new_value", response.getData().get("new_field"));
assertEquals("active", response.getData().get("status")); // Should still exist
}

@Test
void testCreateMultipleWorkingMemoriesAndRetrieveEach() throws Exception {
String namespace = "integration-test-multiple";
String sessionId1 = "multi-session-1-" + UUID.randomUUID();
String sessionId2 = "multi-session-2-" + UUID.randomUUID();
String sessionId3 = "multi-session-3-" + UUID.randomUUID();

// Create three working memories with different content
// Note: userId is part of the Redis key, so we need to use the same userId when retrieving
WorkingMemory memory1 = WorkingMemory.builder()
.sessionId(sessionId1)
.namespace(namespace)
.messages(Collections.singletonList(
MemoryMessage.builder().role("user").content("First session message").build()))
.build();

WorkingMemory memory2 = WorkingMemory.builder()
.sessionId(sessionId2)
.namespace(namespace)
.messages(Collections.singletonList(
MemoryMessage.builder().role("user").content("Second session message").build()))
.build();

WorkingMemory memory3 = WorkingMemory.builder()
.sessionId(sessionId3)
.namespace(namespace)
.messages(Collections.singletonList(
MemoryMessage.builder().role("user").content("Third session message").build()))
.build();

// Store all three working memories
client.workingMemory().putWorkingMemory(sessionId1, memory1, null, null, null, null);
client.workingMemory().putWorkingMemory(sessionId2, memory2, null, null, null, null);
client.workingMemory().putWorkingMemory(sessionId3, memory3, null, null, null, null);

// Small delay to ensure data is persisted
Thread.sleep(200);

// Retrieve each working memory individually and verify
// Note: getWorkingMemory signature is (sessionId, namespace, userId, modelName, contextWindowMax)
WorkingMemoryResponse retrieved1 = client.workingMemory()
.getWorkingMemory(sessionId1, namespace, null, null, null);
assertNotNull(retrieved1);
assertEquals(sessionId1, retrieved1.getSessionId());
assertNotNull(retrieved1.getMessages());
assertFalse(retrieved1.getMessages().isEmpty());
assertEquals("First session message", retrieved1.getMessages().get(0).getContent());

WorkingMemoryResponse retrieved2 = client.workingMemory()
.getWorkingMemory(sessionId2, namespace, null, null, null);
assertNotNull(retrieved2);
assertEquals(sessionId2, retrieved2.getSessionId());
assertNotNull(retrieved2.getMessages());
assertFalse(retrieved2.getMessages().isEmpty());
assertEquals("Second session message", retrieved2.getMessages().get(0).getContent());

WorkingMemoryResponse retrieved3 = client.workingMemory()
.getWorkingMemory(sessionId3, namespace, null, null, null);
assertNotNull(retrieved3);
assertEquals(sessionId3, retrieved3.getSessionId());
assertNotNull(retrieved3.getMessages());
assertFalse(retrieved3.getMessages().isEmpty());
assertEquals("Third session message", retrieved3.getMessages().get(0).getContent());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ void testDeleteWorkingMemory() throws Exception {
.addHeader("Content-Type", "application/json"));

// Execute
AckResponse response = client.workingMemory().deleteWorkingMemory("session-123", "user-456", "test-namespace");
AckResponse response = client.workingMemory().deleteWorkingMemory("session-123", "test-namespace", "user-456");
Copy link

Choose a reason for hiding this comment

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

Test passes userId and namespace in wrong order

Medium Severity

In testPutWorkingMemory, the call putWorkingMemory("session-123", memory, "user-456", "test-namespace", null, null) was not updated for the new parameter order. After the signature change to (sessionId, memory, namespace, userId, ...), this passes "user-456" as namespace and "test-namespace" as userId, which is reversed from the intended values.

Fix in Cursor Fix in Web

Copy link
Collaborator

Choose a reason for hiding this comment

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

@raphaeldelio 👆🏽


// Verify
assertNotNull(response);
Expand Down
Loading