agentscope-ai / agentscope-ai/agentscope-java

[Bug]:AutoContextMemory#summaryPreviousRoundMessages implementation and comment inconsistent

Abierto
#1,178 1 comentario 0 reacciones 0 asignados Ver en GitHub
area/ext/memory bug
Lenguaje dominante
Java
Estrellas
5.6k
Forks
1.3k
Merge medio
4 d 12 h
PR fusionados (30 d)
77

Descripción

**AgentScope-Java is an open-source project. To involve a broader community, we recommend asking your questions in English.**

**Describe the bug**
AutoContextMemory#summaryPreviousRoundMessages implementation and comment inconsistent.
Original comment:
> /**
* Summarize all previous rounds of conversation messages before the latest assistant.
*
*

This method finds the latest assistant message and summarizes all conversation rounds
* before it. Each round consists of messages between a user message and its corresponding
* assistant message (typically including tool calls/results and the assistant message itself).
*
*

Example transformation:
* Before: "user1-tools-assistant1, user2-tools-assistant2, user3-tools-assistant3, user4"
* After: "user1-summary, user2-summary, user3-summary, user4"
* Where each summary contains the compressed information from tools and assistant of that round.
*
*

Strategy:
* 1. Find the latest assistant message (this is the current round, not to be summarized)
* 2. From the beginning, find all user-assistant pairs before the latest assistant
* 3. For each pair, summarize messages between user and assistant (including assistant message)
* 4. Replace those messages (including assistant) with summary (process from back to front to avoid index shifting)
*
* @param rawMessages the list of messages to process
* @return true if summary was actually performed, false otherwise
*/

According to 'Summarize all previous rounds of conversation messages before the latest assistant' in comment and code implementation, for 'the 'Example transformation', 'user3-tools-assistant3' will not be summarized. The correct content is as follows:
> * Before: "user1-tools-assistant1, user2-tools-assistant2, user3-tools-assistant3, user4"
* After: "user1-summary, user2-summary, **user3-tools-assistant3,** user4"

AutoContextMemory#summaryPreviousRoundMessages will not summary last pair, when last pair has too many messages, it will trigger a large amount of context.

**To Reproduce**
Steps to reproduce the behavior:

Branch: release/1.0.10
Method: AutoContextMemory#summaryPreviousRoundMessages

1. You code
```java
private boolean summaryPreviousRoundMessages(List rawMessages) {
if (rawMessages == null || rawMessages.isEmpty()) {
return false;
}

// Step 1: Find the latest assistant message that is a final response (not a tool call)
int latestAssistantIndex = -1;
for (int i = rawMessages.size() - 1; i >= 0; i--) {
Msg msg = rawMessages.get(i);
if (MsgUtils.isFinalAssistantResponse(msg)) {
latestAssistantIndex = i;
break;
}
}

// If no assistant message found, nothing to summarize
if (latestAssistantIndex < 0) {
return false;
}

// Step 2: Find all user-assistant pairs before the latest assistant
// We'll collect them as pairs: (userIndex, assistantIndex)
List> userAssistantPairs = new ArrayList<>();
int currentUserIndex = -1;

for (int i = 0; i < latestAssistantIndex; i++) {
Msg msg = rawMessages.get(i);
if (msg.getRole() == MsgRole.USER) {
currentUserIndex = i;
} else if (MsgUtils.isFinalAssistantResponse(msg) && currentUserIndex >= 0) {
// Found a user-assistant pair (assistant message is a final response, not a tool
// call)
if (i - currentUserIndex != 1) {
userAssistantPairs.add(new Pair<>(currentUserIndex, i));
}

currentUserIndex = -1; // Reset to find next pair
}
}

// If no pairs found, nothing to summarize
if (userAssistantPairs.isEmpty()) {
return false;
}

log.info(
"Found {} user-assistant pairs to summarize before latest assistant at index {}",
userAssistantPairs.size(),
latestAssistantIndex);

// Step 3: Process pairs from back to front to avoid index shifting issues
boolean hasSummarized = false;
for (int pairIdx = userAssistantPairs.size() - 1; pairIdx >= 0; pairIdx--) {
Pair pair = userAssistantPairs.get(pairIdx);
int userIndex = pair.first();
int assistantIndex = pair.second();

// Messages to summarize: from user to assistant (inclusive of both)
// Include user message for context, but we'll only remove messages after user
int startIndex = userIndex + 1; // Messages to remove start after user
int endIndex = assistantIndex; // Include assistant message in removal

// If no messages between user and assistant (including assistant), skip
if (startIndex > endIndex) {
log.info(
"No messages to summarize between user at index {} and assistant at index"
+ " {}",
userIndex,
assistantIndex);
continue;
}

// Include user message in messagesToSummarize for context, but keep it in the final
// list
List messagesToSummarize = new ArrayList<>();
messagesToSummarize.add(rawMessages.get(userIndex)); // Include user message for context
for (int i = startIndex; i <= endIndex; i++) {
messagesToSummarize.add(rawMessages.get(i));
}

log.info(
"Summarizing round {}: user at index {}, messages [{}, {}], totalCount={}"
+ " (includes user message for context)",
pairIdx + 1,
userIndex,
startIndex,
endIndex,
messagesToSummarize.size());

// Step 4: Check if original token count is sufficient for compression
// Skip compression if tokens are below threshold to avoid compression overhead
int originalTokens = TokenCounterUtil.calculateToken(messagesToSummarize);
int threshold = autoContextConfig.getMinCompressionTokenThreshold();
if (originalTokens < threshold) {
log.info(
"Skipping conversation summary for round {}: original tokens ({}) is below"
+ " threshold ({})",
pairIdx + 1,
originalTokens,
threshold);
continue;
}

log.info(
"Proceeding with conversation summary for round {}: original tokens: {},"
+ " threshold: {}",
pairIdx + 1,
originalTokens,
threshold);

// Step 5: Offload original messages if contextOffLoader is available
String uuid = UUID.randomUUID().toString();
offload(uuid, messagesToSummarize);
log.info("Offloaded messages to be summarized: uuid={}", uuid);

// Step 6: Generate summary
Msg summaryMsg = summaryPreviousRoundConversation(messagesToSummarize, uuid);

// Build metadata for compression event
Map metadata = new HashMap<>();
if (summaryMsg.getChatUsage() != null) {
metadata.put("inputToken", summaryMsg.getChatUsage().getInputTokens());
metadata.put("outputToken", summaryMsg.getChatUsage().getOutputTokens());
metadata.put("time", summaryMsg.getChatUsage().getTime());
}

// Record compression event (before removing messages to preserve indices)
recordCompressionEvent(
CompressionEvent.PREVIOUS_ROUND_CONVERSATION_SUMMARY,
startIndex,
endIndex,
rawMessages,
summaryMsg,
metadata);

// Step 7: Remove the messages between user and assistant (including assistant), then
// replace with summary
// Since we're processing from back to front, the indices are still accurate
// for the current pair (indices of pairs after this one have already been adjusted)

// Remove messages from startIndex to endIndex (including assistant, from back to front
// to avoid index shifting)
int removedCount = endIndex - startIndex + 1;
rawMessages.subList(startIndex, endIndex + 1).clear();

// After removal, the position where assistant was is now: assistantIndex - removedCount
// + 1
// But since we removed everything including assistant, we insert summary at the
// position after user
int insertIndex = userIndex + 1;

// Insert summary after user (replacing the removed messages including assistant)
rawMessages.add(insertIndex, summaryMsg);

log.info(
"Replaced {} messages [indices {}-{}] with summary at index {}",
removedCount,
startIndex,
endIndex,
insertIndex);

hasSummarized = true;
}

return hasSummarized;
}
```

2. How to execute
3. See error
**Expected behavior**

According to 'Summarize all previous rounds of conversation messages before the latest assistant' in comment and code implementation, for 'the 'Example transformation', 'user3-tools-assistant3' will not be summarized. The correct content is as follows:
> * Before: "user1-tools-assistant1, user2-tools-assistant2, user3-tools-assistant3, user4"
* After: "user1-summary, user2-summary, **user3-tools-assistant3,** user4"

AutoContextMemory#summaryPreviousRoundMessages will not summary last pair, when last pair has too many messages, it will trigger a large amount of context.

**Error messages**
Detailed error messages.

**Environment (please complete the following information):**

- AgentScope-Java Version: release/1.0.10
- Java Version: [e.g. 17]
- OS: [e.g. macos]

**Additional context**
Add any other context about the problem here.

Guía de contribución

Abrir la guía de contribución

Evaluación

Este issue todavía no se ha evaluado.

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.