Skip to content

fix(autocontext): add error handling to AutoContextHook.handlePreReasoning() #1317

Closed
xiaoqingwanga wants to merge 4 commits into
agentscope-ai:mainfrom
xiaoqingwanga:fix/autocontext-hook-pre-reasoning-error-handling
Closed

fix(autocontext): add error handling to AutoContextHook.handlePreReasoning() #1317
xiaoqingwanga wants to merge 4 commits into
agentscope-ai:mainfrom
xiaoqingwanga:fix/autocontext-hook-pre-reasoning-error-handling

Conversation

@xiaoqingwanga

Copy link
Copy Markdown

AgentScope-Java Version

1.0.12-SNAPSHOT

Description

Background

AutoContextHook.handlePreReasoning() does not have error handling. When the blocking model call inside AutoContextMemory.compressIfNeeded() (model.stream().block()) fails due to timeout, service errors, or rate limiting, the exception propagates without being handled, causing the Agent’s reactive pipeline to silently crash. The only trace is an AGENT_CALL_END event in tracing with "exception":"value", preceded by an approximately 10-second blank period, which corresponds to the model call timeout window.

By contrast, handlePreCall() already has a try-catch(Exception) block and continues execution after errors. handlePreReasoning() is missing the same protection.

Changes

AutoContextHook.java

  • Wrapped the entire body of handlePreReasoning() in a try-catch block, aligning it with the existing pattern in handlePreCall().
  • For non-interruption exceptions, such as model timeouts or rate limiting: log a WARN message and return the original event. The Agent continues running with uncompressed messages, providing graceful degradation.
  • For exceptions containing an InterruptedException, where Reactor .block() wraps checked exceptions in a RuntimeException: detect it by walking the cause chain, then return Mono.error(e) to correctly propagate the interruption signal.
  • Added a private helper method, isInterruptedException(Throwable), which walks through getCause() level by level to detect InterruptedException.
  • Updated the Javadoc for handlePreReasoning() to document the new error-handling behavior.

AutoContextHookTest.java

  • Added testPreReasoningEventHandlesCompressionError: uses a FailingModel that throws RuntimeException, triggers strategy-4 compression, and verifies that the hook returns the original event instead of throwing an exception.
  • Added testPreReasoningEventPreservesWrappedInterruptedException: uses a FailingModel that throws RuntimeException(new InterruptedException(...)), and verifies that the wrapped interruption exception is correctly propagated through Mono.error().
  • Added the FailingModel test helper class.

How to test

# Run the newly added tests
mvn test -pl agentscope-extensions/agentscope-extensions-autocontext-memory \
  -Dtest="AutoContextHookTest#testPreReasoningEventHandlesCompressionError+testPreReasoningEventPreservesWrappedInterruptedException"

# Run the full module test suite: 183 tests
mvn test -pl agentscope-extensions/agentscope-extensions-autocontext-memory

Checklist

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

xiaoqingwanga and others added 3 commits April 29, 2026 16:28
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
compressIfNeeded() makes blocking model calls that can fail with timeout,
service error, or rate limit. Without a try-catch, the exception kills the
agent's reactive pipeline. Mirror handlePreCall()'s existing pattern:
catch, log at WARN, and continue with uncompressed messages.

Walk the cause chain for InterruptedException to preserve thread
interruption semantics (Reactor's .block() wraps checked exceptions).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@xiaoqingwanga
xiaoqingwanga requested a review from a team April 29, 2026 10:31
@CLAassistant

CLAassistant commented Apr 29, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@codecov

codecov Bot commented Apr 29, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@LearningGp

Copy link
Copy Markdown
Member
image

…pre-reasoning-error-handling

# Conflicts:
#	agentscope-extensions/agentscope-extensions-autocontext-memory/src/main/java/io/agentscope/core/memory/autocontext/AutoContextHook.java
#	agentscope-extensions/agentscope-extensions-autocontext-memory/src/test/java/io/agentscope/core/memory/autocontext/AutoContextHookTest.java
@xiaoqingwanga

xiaoqingwanga commented May 21, 2026

Copy link
Copy Markdown
Author
image

hi, the conflicts are resolved. pls review the changes. @LearningGp

@LearningGp LearningGp left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Placing onErrorResume after .map(...) inadvertently catches exceptions thrown by buildInputMessages (even if rare) and swallows them with a misleading "Failed to compress context" log. I'd suggest chaining onErrorResume directly after compressIfNeededAsync() so exceptions inside .map can bubble up normally.

@xiaoqingwanga

Copy link
Copy Markdown
Author

Placing onErrorResume after .map(...) inadvertently catches exceptions thrown by buildInputMessages (even if rare) and swallows them with a misleading "Failed to compress context" log. I'd suggest chaining onErrorResume directly after compressIfNeededAsync() so exceptions inside .map can bubble up normally.

Yeah, this solution does help. BUT excptions from buildInputMessages are really rare. And if we apply the optimization, we'll re-introduce the original problem - if an exception happens inside the map, the compression disrupts the agent execution again.

@AgentScopeJavaBot AgentScopeJavaBot added enhancement New feature or request area/ext/memory Memory/session extension implementations labels May 28, 2026

@LearningGp LearningGp left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM

@LearningGp

Copy link
Copy Markdown
Member
image

@xiaoqingwanga

Copy link
Copy Markdown
Author

Close this PR because the compaction has been refactored.

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

Labels

area/ext/memory Memory/session extension implementations enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants