Skip to content

feat(event): emit COMPACTION_START/END events from CompactionMiddleware#1962

Open
Buktal wants to merge 11 commits into
agentscope-ai:mainfrom
Buktal:feat/compaction-events
Open

feat(event): emit COMPACTION_START/END events from CompactionMiddleware#1962
Buktal wants to merge 11 commits into
agentscope-ai:mainfrom
Buktal:feat/compaction-events

Conversation

@Buktal

@Buktal Buktal commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

AgentScope-Java Version

2.0.0-SNAPSHOT

Description

Fixes #1905.

Background: When CompactionMiddleware triggers context compaction (a summarization LLM call), the frontend receives no events during this period and appears frozen.

Changes:

  • Add COMPACTION_START and COMPACTION_END to AgentEventType
  • Add CompactionStartEvent (carries estimatedTokens, triggerThreshold) and CompactionEndEvent (carries originalMessageCount, compactedMessageCount, estimatedTokensSaved)
  • Register both events in AgentEvent @JsonSubTypes
  • CompactionMiddleware.onReasoning() wraps the reasoning stream with COMPACTION_START → stream → COMPACTION_END when compaction is actually triggered (events are not emitted when the token threshold is not reached)

Testing: Full build passes (mvn clean install). The events fire only when compaction triggers, consistent with the existing event model (e.g. MODEL_CALL_START/END).

Checklist

  • Code has been formatted with mvn spotless:apply
  • All tests are passing (mvn test)
  • Javadoc comments are complete and follow project conventions
  • Related documentation has been updated (e.g. links, examples, etc.)
  • Code is ready for review

When context compaction is triggered, CompactionMiddleware now emits
COMPACTION_START before the summarization LLM call and COMPACTION_END
after reasoning completes, allowing frontends to display progress
instead of appearing frozen. Events carry token statistics so callers
can show meaningful progress information.

Closes agentscope-ai#1905
@Buktal Buktal requested a review from a team June 29, 2026 11:46
@codecov

codecov Bot commented Jun 29, 2026

Copy link
Copy Markdown

…ent and CompactionMiddleware

- CompactionEventRoundTrip in AgentEventStreamTest: JSON serialization/deserialization
  round-trip via Jackson polymorphism for both compaction event types; field values and
  type discriminator are verified
- CompactionMiddlewareTest: covers the four execution paths — no compaction (passthrough),
  compaction triggered (START/END wrap next flux), non-ReActAgent short-circuit, and
  compaction error fallback
Buktal added 3 commits July 7, 2026 11:17
Previously COMPACTION_START was emitted inside flatMapMany after the
compactIfNeeded Mono completed, causing the frontend to appear stuck
during the actual compaction wait period.

Now the middleware performs a lightweight threshold pre-check and emits
COMPACTION_START immediately before the compaction Mono subscribes.
COMPACTION_END fires right after compaction completes, before reasoning
output begins. All paths (success, skip, error) properly close the
START/END pair so the frontend never hangs in loading state.
@Buktal Buktal requested a review from jujn July 7, 2026 05:55
@jujn

jujn commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Test failed:
image

Buktal added 3 commits July 8, 2026 13:48
The test asserted inner events appeared between START and END, but the
actual middleware contract is START → END → inner (compaction finishes
before reasoning begins). Also improved the error-path test to use a low
threshold config that actually enters the compaction branch, ensuring the
START/END pairing contract is verified on error recovery.
Tests that call agent.call() without closing the agent leave background
resources (session writers, task repositories) running, causing JUnit
@tempdir cleanup to fail with DirectoryNotEmptyException.

Wrap agent construction in try-with-resources to ensure proper shutdown
before temp directory deletion.
@Buktal

Buktal commented Jul 8, 2026

Copy link
Copy Markdown
Contributor Author

Test failed: image

Resolved the assertion issue in CompactionMiddlewareTest where COMPACTION_END event order was incorrect.

@jujn jujn left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Additionally, it is suggested to narrow down the PR description from "Fixes1905" to partial fixes (including only COMPACTION-START/END events)

Move onErrorResume before flatMapMany so it only catches errors from
compactIfNeeded(), not from downstream next.apply() execution. This
prevents duplicate model/tool execution and misleading compaction end
events when downstream reasoning fails after a successful compaction.
@oss-maintainer

Copy link
Copy Markdown
Collaborator

⚠️ Merge conflict detected

This PR has conflicts with the main branch and cannot be merged. Please rebase or merge main into your branch and resolve the conflicts:

git fetch origin
git checkout feat/compaction-events
git rebase origin/main
# resolve conflicts, then:
git push --force-with-lease

This is a one-time reminder. Feel free to @mention me for a re-review after conflicts are resolved.


Automated notification by github-manager-bot

@AgentScopeJavaBot AgentScopeJavaBot added enhancement New feature or request area/core/agent Agent runtime, pipeline, hooks, plan labels Jul 11, 2026

@AgentScopeJavaBot AgentScopeJavaBot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

🤖 AI Review

Adds COMPACTION_START/END events from CompactionMiddleware. Good observability addition. Design concerns: START fires speculatively (ambiguous cancel), triggerThreshold misleading for message-count triggers, estimatedTokensSaved could be negative.

(inline comments could not be attached — line numbers fell outside PR hunks. See archived report.)

Buktal added 2 commits July 13, 2026 12:01
…t semantics

Address PR review feedback on the COMPACTION_START/END events:

* Split ConversationCompactor into probe() + execute(): probe runs the
  non-LLM truncate/prune passes and locates a safe cutoff without side
  effects, returning a sealed CompactionDecision (Proceed | Skip).
  CompactionMiddleware now emits COMPACTION_START only when compaction
  will actually run, eliminating the speculative-start / synthetic-end
  pair emitted when internal skip paths were hit. compactIfNeeded() is
  kept as a convenience wrapper for existing callers.
* CompactionStartEvent gains a TriggerReason enum (TOKEN_THRESHOLD /
  MESSAGE_THRESHOLD), thresholdValue, and messageCount so consumers can
  interpret the fired dimension. Legacy `triggerThreshold` JSON is still
  accepted via @JsonAlias; getTriggerThreshold() is @deprecated.
* CompactionEndEvent gains an Outcome enum (COMPACTED / FAILED) plus
  beforeTokens / afterTokens observations. getEstimatedTokensSaved() is
  retained as a @deprecated derived accessor; it may be negative when
  the preserved tail outweighs the removed prefix — documented, not
  masked.

Tests updated to cover the new fields, the legacy JSON alias round-trip,
and the FAILED outcome on the compaction error path. No behaviour change
in the happy path; skip paths now produce no compaction events at all.
# Conflicts:
#	agentscope-core/src/main/java/io/agentscope/core/event/AgentEvent.java
#	agentscope-core/src/main/java/io/agentscope/core/event/AgentEventType.java
@Buktal

Buktal commented Jul 13, 2026

Copy link
Copy Markdown
Contributor Author

@oss-maintainer Conflicts resolved. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/core/agent Agent runtime, pipeline, hooks, plan enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: 希望支持compact事件、toolResultEviction等事件通过streamEvent透出

4 participants