feat: auto context memory with plan note book#363
feat: auto context memory with plan note book#363AlbumenJ merged 4 commits intoagentscope-ai:mainfrom
Conversation
Change-Id: I57ae184002b82e199c618009d3b6d23a65d2c363
…extHook的必要性 更新了 README 文件,添加关于新功能“计划感知”的说明以及强调使用 `AutoContextHook` 的必要性。此外,还更新了最佳实践部分,明确了在使用 `AutoContextMemory` 时必须使用 `AutoContextHook`。 Change-Id: I01da7037c6772e0f00ca0440846b49a93bbaa9a1 Co-developed-by: Aone Copilot <noreply@alibaba-inc.com>
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
There was a problem hiding this comment.
Pull request overview
This PR introduces plan-aware compression to AutoContextMemory by integrating with PlanNotebook. The main enhancement is the creation of AutoContextHook, which automatically registers ContextOffloadTool and attaches PlanNotebook to enable intelligent compression that preserves plan-related context. The PR also simplifies the AutoContextConfig API by removing setter methods in favor of a builder-only pattern.
Key Changes:
- Introduced AutoContextHook for automatic setup of AutoContextMemory with ReActAgent
- Added plan-aware compression that prioritizes plan-related information during context compression
- Removed setter methods from AutoContextConfig to enforce builder-based configuration
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 11 comments.
Show a summary per file
| File | Description |
|---|---|
| AutoContextMemory.java | Added attachPlanNote method and plan-aware compression logic that inserts plan context hints into compression prompts |
| AutoContextHook.java | New hook that automatically registers ContextOffloadTool and attaches PlanNotebook on first agent call |
| AutoContextConfig.java | Removed all setter methods to enforce builder-only API pattern |
| AutoContextMemoryTest.java | Added tests for PlanNotebook attachment and plan-aware compression behavior |
| AutoContextHookTest.java | New comprehensive test suite for AutoContextHook functionality |
| AutoContextConfigTest.java | Updated tests to remove setter method tests and add currentRoundCompressionRatio coverage |
| README.md | Updated documentation to mandate AutoContextHook usage and document plan-aware compression |
| README_zh.md | Chinese translation of documentation updates |
| AutoMemoryExample.java | Updated example to use AutoContextHook instead of manual ContextOffloadTool registration |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| long inProgressCount = | ||
| subtasks != null | ||
| ? subtasks.stream() | ||
| .filter(st -> st.getState() == SubTaskState.IN_PROGRESS) | ||
| .count() | ||
| : 0; | ||
| long doneCount = | ||
| subtasks != null | ||
| ? subtasks.stream().filter(st -> st.getState() == SubTaskState.DONE).count() | ||
| : 0; |
There was a problem hiding this comment.
The method iterates through subtasks twice to count states (lines 1552-1561). This is inefficient and can be optimized by counting both states in a single iteration. For better performance, combine the two stream operations into one pass.
| long inProgressCount = | |
| subtasks != null | |
| ? subtasks.stream() | |
| .filter(st -> st.getState() == SubTaskState.IN_PROGRESS) | |
| .count() | |
| : 0; | |
| long doneCount = | |
| subtasks != null | |
| ? subtasks.stream().filter(st -> st.getState() == SubTaskState.DONE).count() | |
| : 0; | |
| long inProgressCount = 0; | |
| long doneCount = 0; | |
| if (subtasks != null) { | |
| for (SubTask subTask : subtasks) { | |
| SubTaskState state = subTask.getState(); | |
| if (state == SubTaskState.IN_PROGRESS) { | |
| inProgressCount++; | |
| } else if (state == SubTaskState.DONE) { | |
| doneCount++; | |
| } | |
| } | |
| } |
| private final AtomicBoolean registered = new AtomicBoolean(false); | ||
|
|
||
| /** | ||
| * Creates a new AutoContextHook. | ||
| * | ||
| * <p>The hook will automatically detect AutoContextMemory from the agent's memory | ||
| * when processing PreCallEvent. | ||
| */ | ||
| public AutoContextHook() { | ||
| // No parameters needed - memory is obtained from the event | ||
| } | ||
|
|
||
| @Override | ||
| public <T extends HookEvent> Mono<T> onEvent(T event) { | ||
| if (event instanceof PreCallEvent preCallEvent) { | ||
| @SuppressWarnings("unchecked") | ||
| Mono<T> result = (Mono<T>) handlePreCall(preCallEvent); | ||
| return result; | ||
| } | ||
| return Mono.just(event); | ||
| } | ||
|
|
||
| @Override | ||
| public int priority() { | ||
| // High priority to execute early in the hook chain | ||
| return 50; | ||
| } | ||
|
|
||
| /** | ||
| * Handles PreCallEvent by registering AutoContextMemory integration. | ||
| * | ||
| * <p>This method checks if the agent is a ReActAgent and if its memory is an | ||
| * AutoContextMemory instance. If so, and if this is the first time processing, | ||
| * it: | ||
| * <ol> | ||
| * <li>Registers ContextOffloadTool to the agent's toolkit</li> | ||
| * <li>Attaches the agent's PlanNotebook to AutoContextMemory (if available)</li> | ||
| * </ol> | ||
| * | ||
| * @param event the PreCallEvent | ||
| * @return Mono containing the unmodified event | ||
| */ | ||
| private Mono<PreCallEvent> handlePreCall(PreCallEvent event) { | ||
| // Check if we've already registered | ||
| if (registered.get()) { | ||
| return Mono.just(event); | ||
| } | ||
|
|
||
| Agent agent = event.getAgent(); | ||
|
|
||
| // Only process ReActAgent instances | ||
| if (!(agent instanceof ReActAgent reActAgent)) { | ||
| return Mono.just(event); | ||
| } | ||
|
|
||
| // Get memory from agent and verify it's an AutoContextMemory instance | ||
| Memory memory = reActAgent.getMemory(); | ||
| if (!(memory instanceof AutoContextMemory autoContextMemory)) { | ||
| return Mono.just(event); | ||
| } | ||
|
|
||
| // Try to set the flag atomically (only one thread will succeed) | ||
| if (!registered.compareAndSet(false, true)) { | ||
| // Another thread already registered | ||
| return Mono.just(event); | ||
| } |
There was a problem hiding this comment.
The hook uses an instance-level AtomicBoolean to track registration state, which means it only works correctly if a single AutoContextHook instance is used per agent. If multiple agent instances share the same hook instance, only the first agent will be properly configured. The flag should be tracked per-agent, not per-hook instance. Consider using a ConcurrentHashMap with the agent instance as the key to track registration state per agent.
| .hook(new AutoContextHook()) // Register the hook for automatic setup | ||
| .build(); | ||
| String sessionId = "session000005"; | ||
| String sessionId = "session000005_1324541111"; |
There was a problem hiding this comment.
The sessionId contains what appears to be a timestamp suffix "1324541111", but this value is actually in the past (represents a date in 2011). If this is intended as a timestamp, it should use the current timestamp. If it's just an example ID, consider using a more descriptive suffix to avoid confusion.
| String sessionId = "session000005_1324541111"; | |
| String sessionId = "session_example_0005"; |
|
|
||
| ### AutoContextHook | ||
|
|
||
| 一个 `PreCallHook`,**必须**用于设置 `AutoContextMemory` 与 `ReActAgent` 的集成: |
There was a problem hiding this comment.
The documentation describes AutoContextHook as a "PreCallHook", but it actually implements the Hook interface, not a specific PreCallHook interface. The documentation should be corrected to accurately describe it as a Hook that handles PreCallEvent, rather than calling it a "PreCallHook" which suggests a different type.
| 一个 `PreCallHook`,**必须**用于设置 `AutoContextMemory` 与 `ReActAgent` 的集成: | |
| 一个处理 `PreCallEvent` 的 `Hook`,**必须**用于设置 `AutoContextMemory` 与 `ReActAgent` 的集成: |
|
|
||
| - 自动将 `ContextOffloadTool` 注册到 agent 的 toolkit | ||
| - 自动将 agent 的 `PlanNotebook` 附加到 `AutoContextMemory`,实现计划感知压缩(如果启用了 PlanNotebook) | ||
| - 每个 agent 只执行一次(线程安全) |
There was a problem hiding this comment.
The documentation claims the hook "Executes only once per agent (thread-safe)", but the implementation uses an instance-level AtomicBoolean that tracks registration globally for the hook instance, not per-agent. This means if the same hook instance is used for multiple agents, only the first agent will be configured. The documentation should be updated to reflect the actual behavior, or the implementation should be fixed to truly support per-agent registration tracking.
| - 每个 agent 只执行一次(线程安全) | |
| - 每个 `AutoContextHook` 实例只会在其绑定的第一个 agent 上执行一次(线程安全);如需为多个 agent 启用自动配置,请为每个 agent 创建独立的 `AutoContextHook` 实例 |
| try { | ||
| java.lang.reflect.Field planField = PlanNotebook.class.getDeclaredField("currentPlan"); | ||
| planField.setAccessible(true); | ||
| planField.set(planNotebook, plan); | ||
| } catch (Exception e) { | ||
| // If reflection fails, skip this test | ||
| return; | ||
| } |
There was a problem hiding this comment.
This test uses reflection to set a private field, which is fragile and silently fails if the field name changes or if reflection fails. The test silently returns on exception (line 810), which means it passes even if the reflection fails and the actual test logic is never executed. Consider using a proper builder method or public API to set the plan, or if reflection is necessary for testing, make the test fail explicitly rather than silently skipping.
|
|
||
| ### AutoContextHook | ||
|
|
||
| A `PreCallHook` that **must** be used to set up `AutoContextMemory` integration with `ReActAgent`: |
There was a problem hiding this comment.
The documentation describes AutoContextHook as a "PreCallHook", but it actually implements the Hook interface, not a specific PreCallHook interface. The documentation should be corrected to accurately describe it as a Hook that handles PreCallEvent, rather than calling it a "PreCallHook" which suggests a different type.
| A `PreCallHook` that **must** be used to set up `AutoContextMemory` integration with `ReActAgent`: | |
| A `Hook` handling `PreCallEvent` that **must** be used to set up `AutoContextMemory` integration with `ReActAgent`: |
|
|
||
| - Automatically registers `ContextOffloadTool` to the agent's toolkit | ||
| - Automatically attaches the agent's `PlanNotebook` to `AutoContextMemory` for plan-aware compression (if PlanNotebook is enabled) | ||
| - Executes only once per agent (thread-safe) |
There was a problem hiding this comment.
The documentation claims the hook "Executes only once per agent (thread-safe)", but the implementation uses an instance-level AtomicBoolean that tracks registration globally for the hook instance, not per-agent. This means if the same hook instance is used for multiple agents, only the first agent will be configured. The documentation should be updated to reflect the actual behavior, or the implementation should be fixed to truly support per-agent registration tracking.
| - Executes only once per agent (thread-safe) | |
| - Executes at most once per `AutoContextHook` instance (thread-safe). To ensure per-agent setup, create a separate `AutoContextHook` instance for each agent. |
| @BeforeEach | ||
| void setUp() { | ||
| config = AutoContextConfig.builder().msgThreshold(10).maxToken(1000).build(); | ||
| memory = new AutoContextMemory(config, mockModel); | ||
| hook = new AutoContextHook(); | ||
| toolkit = new Toolkit(); | ||
| agent = createTestReActAgent(memory, toolkit); | ||
| } |
There was a problem hiding this comment.
The test reuses the same hook instance and toolkit across multiple test methods via the @beforeeach setup. This can cause test interference because the hook's AtomicBoolean registered flag remains set after the first test that triggers it. Tests that run after testFirstPreCallEvent may fail or have unexpected behavior because the hook won't register again. Each test should either create a fresh hook instance or reset the hook state between tests.
| public void attachPlanNote(PlanNotebook planNotebook) { | ||
| this.planNotebook = planNotebook; | ||
| if (planNotebook != null) { | ||
| log.debug("PlanNotebook attached to AutoContextMemory for plan-aware compression"); | ||
| } else { | ||
| log.debug("PlanNotebook detached from AutoContextMemory"); | ||
| } | ||
| } |
There was a problem hiding this comment.
The planNotebook field is not marked as volatile, and the attachPlanNote method is not synchronized. If this method is called from one thread while another thread is reading the planNotebook in getPlanStateContext, it could lead to visibility issues where the reading thread might not see the updated value. Consider making the planNotebook field volatile to ensure proper visibility across threads, or synchronize access to this field.
此提交更新了多个压缩策略的提示词命名,并调整了部分逻辑处理方式,使得代码更加简洁易读。同时增加了对特定消息类型的标记以便于后续处理。 Change-Id: I24c4cf89564feb259ad76b0768a4d0329989f94a Co-developed-by: Aone Copilot <noreply@alibaba-inc.com>
移除了重复的 `agentscope-core` 依赖配置,并将消息内容从单个块改为列表形式。这使得消息结构更加灵活且一致。 Change-Id: I2de97c847c4834386f3641122f1b66d6f8871ec6 Co-developed-by: Aone Copilot <noreply@alibaba-inc.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 13 out of 13 changed files in this pull request and generated 11 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| .hook(new AutoContextHook()) // Register the hook for automatic setup | ||
| .build(); | ||
| String sessionId = "session000005"; | ||
| String sessionId = "session111111111111"; |
There was a problem hiding this comment.
The sessionId has been changed from "session000005" to "session111111111111". This appears to be an arbitrary change that doesn't relate to the PR's purpose of adding AutoContextMemory improvements. If this was changed for testing purposes, it should be reverted to maintain consistency. If there's a specific reason for this change, it should be documented.
| String sessionId = "session111111111111"; | |
| String sessionId = "session000005"; |
| .withSession(new JsonSession(sessionPath)) | ||
| .addComponent(agent) // Automatically named "agent" | ||
| .addComponent(memory); // Automatically named "memory" | ||
| .addComponent(agent); // Automatically named "agent" |
There was a problem hiding this comment.
The removal of the memory component from SessionManager at line 103 (previously "addComponent(memory)") may affect session persistence. If the memory state needs to be saved and restored across sessions, it should still be registered with the SessionManager. Verify that this removal doesn't break the session save/load functionality for AutoContextMemory, or document why it's no longer needed.
| .addComponent(agent); // Automatically named "agent" | |
| .addComponent(agent) // Automatically named "agent" | |
| .addComponent(memory); |
| List<SubTask> subtasks = currentPlan.getSubtasks(); | ||
| if (subtasks != null && !subtasks.isEmpty()) { | ||
| planContext.append("\nSubtasks:\n"); | ||
| for (int i = 0; i < subtasks.size(); i++) { | ||
| SubTask subtask = subtasks.get(i); | ||
| planContext.append( | ||
| String.format( | ||
| " [%d] %s - State: %s\n", | ||
| i + 1, subtask.getName(), subtask.getState().getValue())); | ||
| if (subtask.getState() == SubTaskState.IN_PROGRESS) { | ||
| planContext.append( | ||
| " ⚠️ Currently in progress - preserve related information\n"); | ||
| } else if (subtask.getState() == SubTaskState.DONE | ||
| && subtask.getOutcome() != null) { | ||
| planContext.append(" ✅ Outcome: ").append(subtask.getOutcome()).append("\n"); | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
In getPlanStateContext method, the method accesses currentPlan.getSubtasks() and then checks if it's not null. However, if getSubtasks() returns null, calling .stream() on it at lines 1521-1522 and 1527 will cause a NullPointerException. The null checks for inProgressCount and doneCount calculations need to be applied consistently, or the subtasks list should be guaranteed to be non-null.
| } catch (Exception e) { | ||
| // Log error but don't interrupt the flow | ||
| log.error( | ||
| "Failed to register AutoContextMemory integration for agent: {}", | ||
| agent.getClass().getSimpleName(), | ||
| e); | ||
| // Reset flag so we can retry on next call | ||
| registered.set(false); |
There was a problem hiding this comment.
The error handling at lines 171-178 logs the error and resets the registered flag to allow retry on next call. However, this could lead to repeated failures being logged and attempted on every subsequent call if the underlying issue is persistent (e.g., incompatible agent configuration). Consider adding a maximum retry count or a different strategy to handle persistent failures, such as marking the agent as incompatible after a certain number of failures.
| Mem0LongTermMemory longTermMemory = builder.build(); | ||
| AutoContextConfig autoContextConfig = | ||
| AutoContextConfig.builder().tokenRatio(0.4).lastKeep(10).build(); | ||
| AutoContextConfig.builder().tokenRatio(0.4).lastKeep(20).build(); |
There was a problem hiding this comment.
The lastKeep configuration value has been changed from 10 to 20 at line 75. While this may be a valid adjustment, it's unrelated to the main purpose of this PR (AutoContextMemory with PlanNotebook integration). Consider whether this change should be part of this PR or if it should be reverted to keep the PR focused on its stated purpose.
| AutoContextConfig.builder().tokenRatio(0.4).lastKeep(20).build(); | |
| AutoContextConfig.builder().tokenRatio(0.4).lastKeep(10).build(); |
| /** | ||
| * Attaches a PlanNotebook instance to enable plan-aware compression. | ||
| * | ||
| * <p>This method should be called after the ReActAgent is created and has a PlanNotebook. | ||
| * When a PlanNotebook is attached, compression operations will automatically include | ||
| * plan context information to preserve plan-related information during compression. | ||
| * | ||
| * <p>This method can be called multiple times to update or replace the PlanNotebook. | ||
| * Passing null will detach the current PlanNotebook and disable plan-aware compression. | ||
| * | ||
| * @param planNotebook the PlanNotebook instance to attach, or null to detach | ||
| */ | ||
| public void attachPlanNote(PlanNotebook planNotebook) { | ||
| this.planNotebook = planNotebook; | ||
| if (planNotebook != null) { | ||
| log.debug("PlanNotebook attached to AutoContextMemory for plan-aware compression"); | ||
| } else { | ||
| log.debug("PlanNotebook detached from AutoContextMemory"); | ||
| } | ||
| } |
There was a problem hiding this comment.
The Javadoc for the attachPlanNote method states "This method can be called multiple times to update or replace the PlanNotebook. Passing null will detach the current PlanNotebook and disable plan-aware compression." However, there is no validation or handling to prevent issues if a partially initialized or invalid PlanNotebook is passed. Consider adding parameter validation or documenting the expected state of the PlanNotebook being attached.
| // Skip compressed current round messages - they are compression results, not real assistant | ||
| // responses | ||
| Map<String, Object> metadata = msg.getMetadata(); | ||
| if (metadata != null) { | ||
| Object compressMeta = metadata.get("_compress_meta"); | ||
| // compressMeta may be null if the key doesn't exist, but instanceof handles null safely | ||
| if (compressMeta != null && compressMeta instanceof Map) { | ||
| @SuppressWarnings("unchecked") | ||
| Map<String, Object> compressMetaMap = (Map<String, Object>) compressMeta; | ||
| if (Boolean.TRUE.equals(compressMetaMap.get("compressed_current_round"))) { | ||
| return false; | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
The condition check at line 347 uses Boolean.TRUE.equals() which is good for null safety. However, the comment at line 338-339 says "Skip compressed current round messages - they are compression results, not real assistant responses" but doesn't explain why this metadata field is being checked. Consider adding more context to the comment explaining what "compressed_current_round" means and why these messages need to be filtered out in this specific method.
| @@ -36,10 +36,7 @@ | |||
| <dependency> | |||
| <groupId>io.agentscope</groupId> | |||
| <artifactId>agentscope-core</artifactId> | |||
There was a problem hiding this comment.
The dependency scope change from "provided" and "optional" to default (compile) scope for agentscope-core makes this extension tightly coupled to the core module. This change should be documented in the PR description or release notes, as it affects how users manage dependencies. Users who previously relied on the "provided" scope may need to adjust their dependency management strategy.
| <artifactId>agentscope-core</artifactId> | |
| <artifactId>agentscope-core</artifactId> | |
| <scope>provided</scope> | |
| <optional>true</optional> |
| public AutoContextHook() { | ||
| // No parameters needed - memory is obtained from the event | ||
| } |
There was a problem hiding this comment.
The AutoContextHook class has comprehensive class-level Javadoc with usage examples, which is excellent. However, according to Java coding standards and the custom guideline requiring all public methods to have Javadoc, the public constructor at line 83 should have Javadoc documentation explaining its purpose and behavior, even though it's currently empty. The existing comment at line 84 should be converted to a proper Javadoc comment.
| /** | ||
| * Attaches a PlanNotebook instance to enable plan-aware compression. | ||
| * | ||
| * <p>This method should be called after the ReActAgent is created and has a PlanNotebook. | ||
| * When a PlanNotebook is attached, compression operations will automatically include | ||
| * plan context information to preserve plan-related information during compression. | ||
| * | ||
| * <p>This method can be called multiple times to update or replace the PlanNotebook. | ||
| * Passing null will detach the current PlanNotebook and disable plan-aware compression. | ||
| * | ||
| * @param planNotebook the PlanNotebook instance to attach, or null to detach | ||
| */ | ||
| public void attachPlanNote(PlanNotebook planNotebook) { | ||
| this.planNotebook = planNotebook; | ||
| if (planNotebook != null) { | ||
| log.debug("PlanNotebook attached to AutoContextMemory for plan-aware compression"); | ||
| } else { | ||
| log.debug("PlanNotebook detached from AutoContextMemory"); | ||
| } | ||
| } |
There was a problem hiding this comment.
The public method attachPlanNote at line 1444 has Javadoc documentation, which is good. However, the Javadoc should follow the standard format with @param tag for the planNotebook parameter. The current documentation describes the parameter inline but doesn't use the proper @param tag that Javadoc tools expect.
This pull request introduces significant improvements to the integration and usage of `AutoContextMemory` within the AgentScope framework, particularly with `ReActAgent`. The main focus is on enforcing the use of `AutoContextHook` for automatic setup and enabling plan-aware compression when `PlanNotebook` is used. Documentation in both English and Chinese has been updated to reflect these changes, and the configuration API has been simplified. ### Integration and Usage Improvements * Enforced usage of `AutoContextHook` when integrating `AutoContextMemory` with `ReActAgent`, ensuring automatic registration of `ContextOffloadTool` and attachment of `PlanNotebook` for plan-aware compression. Documentation and code samples have been updated to make this requirement clear and to demonstrate correct usage. [[1]](diffhunk://#diff-7c742bef59c729a796c94eadecb35feabdfeb392ba25692781b062cdbdb9bd2cR138-R144) [[2]](diffhunk://#diff-7c742bef59c729a796c94eadecb35feabdfeb392ba25692781b062cdbdb9bd2cL154-R172) [[3]](diffhunk://#diff-7c742bef59c729a796c94eadecb35feabdfeb392ba25692781b062cdbdb9bd2cR204-R225) [[4]](diffhunk://#diff-cdf30c14548bb5577afc89c77d1aed7ad8c718e93e47e14568048263f095dffdR138-R144) [[5]](diffhunk://#diff-cdf30c14548bb5577afc89c77d1aed7ad8c718e93e47e14568048263f095dffdL154-R172) [[6]](diffhunk://#diff-cdf30c14548bb5577afc89c77d1aed7ad8c718e93e47e14568048263f095dffdR204-R225) [[7]](diffhunk://#diff-6b9103fbf3a240744117a2bf207e08f728ae356b07f26db47787eb2283beac2dR22-L23) [[8]](diffhunk://#diff-6b9103fbf3a240744117a2bf207e08f728ae356b07f26db47787eb2283beac2dL70-R70) [[9]](diffhunk://#diff-6b9103fbf3a240744117a2bf207e08f728ae356b07f26db47787eb2283beac2dR83-R92) ### PlanNotebook-Aware Compression * Added documentation for plan-aware compression: when `PlanNotebook` is attached, the compression process prioritizes and preserves plan-related information, enhancing context retention for active plans and subtasks. [[1]](diffhunk://#diff-7c742bef59c729a796c94eadecb35feabdfeb392ba25692781b062cdbdb9bd2cR45) [[2]](diffhunk://#diff-7c742bef59c729a796c94eadecb35feabdfeb392ba25692781b062cdbdb9bd2cR187) [[3]](diffhunk://#diff-7c742bef59c729a796c94eadecb35feabdfeb392ba25692781b062cdbdb9bd2cR278-R287) [[4]](diffhunk://#diff-cdf30c14548bb5577afc89c77d1aed7ad8c718e93e47e14568048263f095dffdR45) [[5]](diffhunk://#diff-cdf30c14548bb5577afc89c77d1aed7ad8c718e93e47e14568048263f095dffdR187) [[6]](diffhunk://#diff-cdf30c14548bb5577afc89c77d1aed7ad8c718e93e47e14568048263f095dffdR278-R287) ### Best Practices Updates * Updated best practices to require `AutoContextHook` and recommend enabling `PlanNotebook` for agents using plans, ensuring users benefit from automatic setup and plan-aware context management. [[1]](diffhunk://#diff-7c742bef59c729a796c94eadecb35feabdfeb392ba25692781b062cdbdb9bd2cL341-R385) [[2]](diffhunk://#diff-cdf30c14548bb5577afc89c77d1aed7ad8c718e93e47e14568048263f095dffdL341-R385) ### API Simplification * Removed setter methods from `AutoContextConfig`, making the configuration strictly builder-based for cleaner and safer API usage. [[1]](diffhunk://#diff-0f19c9d04469678819a19772e7d5526316006c9e8727f1b7ceb77f967988d6a2L32-R32) [[2]](diffhunk://#diff-0f19c9d04469678819a19772e7d5526316006c9e8727f1b7ceb77f967988d6a2L64-L123) ### Documentation Consistency * Applied all major documentation changes to both English (`README.md`) and Chinese (`README_zh.md`) guides, ensuring clarity and consistency for all users. [[1]](diffhunk://#diff-7c742bef59c729a796c94eadecb35feabdfeb392ba25692781b062cdbdb9bd2cR138-R144) [[2]](diffhunk://#diff-7c742bef59c729a796c94eadecb35feabdfeb392ba25692781b062cdbdb9bd2cL154-R172) [[3]](diffhunk://#diff-7c742bef59c729a796c94eadecb35feabdfeb392ba25692781b062cdbdb9bd2cR187) [[4]](diffhunk://#diff-7c742bef59c729a796c94eadecb35feabdfeb392ba25692781b062cdbdb9bd2cR204-R225) [[5]](diffhunk://#diff-7c742bef59c729a796c94eadecb35feabdfeb392ba25692781b062cdbdb9bd2cR278-R287) [[6]](diffhunk://#diff-7c742bef59c729a796c94eadecb35feabdfeb392ba25692781b062cdbdb9bd2cL341-R385) [[7]](diffhunk://#diff-cdf30c14548bb5577afc89c77d1aed7ad8c718e93e47e14568048263f095dffdR138-R144) [[8]](diffhunk://#diff-cdf30c14548bb5577afc89c77d1aed7ad8c718e93e47e14568048263f095dffdL154-R172) [[9]](diffhunk://#diff-cdf30c14548bb5577afc89c77d1aed7ad8c718e93e47e14568048263f095dffdR187) [[10]](diffhunk://#diff-cdf30c14548bb5577afc89c77d1aed7ad8c718e93e47e14568048263f095dffdR204-R225) [[11]](diffhunk://#diff-cdf30c14548bb5577afc89c77d1aed7ad8c718e93e47e14568048263f095dffdR278-R287) [[12]](diffhunk://#diff-cdf30c14548bb5577afc89c77d1aed7ad8c718e93e47e14568048263f095dffdL341-R385)## AgentScope-Java Version [The version of AgentScope-Java you are working on, e.g. 1.0.3, check your pom.xml dependency version or run `mvn dependency:tree | grep agentscope-parent:pom`(only mac/linux)] ## Description [Please describe the background, purpose, changes made, and how to test this PR] ## Checklist Please check the following items before code is ready to be reviewed. - [ ] 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
This pull request introduces significant improvements to the integration and usage of
AutoContextMemorywithin the AgentScope framework, particularly withReActAgent. The main focus is on enforcing the use ofAutoContextHookfor automatic setup and enabling plan-aware compression whenPlanNotebookis used. Documentation in both English and Chinese has been updated to reflect these changes, and the configuration API has been simplified.Integration and Usage Improvements
AutoContextHookwhen integratingAutoContextMemorywithReActAgent, ensuring automatic registration ofContextOffloadTooland attachment ofPlanNotebookfor plan-aware compression. Documentation and code samples have been updated to make this requirement clear and to demonstrate correct usage. [1] [2] [3] [4] [5] [6] [7] [8] [9]PlanNotebook-Aware Compression
PlanNotebookis attached, the compression process prioritizes and preserves plan-related information, enhancing context retention for active plans and subtasks. [1] [2] [3] [4] [5] [6]Best Practices Updates
AutoContextHookand recommend enablingPlanNotebookfor agents using plans, ensuring users benefit from automatic setup and plan-aware context management. [1] [2]API Simplification
AutoContextConfig, making the configuration strictly builder-based for cleaner and safer API usage. [1] [2]Documentation Consistency
README.md) and Chinese (README_zh.md) guides, ensuring clarity and consistency for all users. [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12]## AgentScope-Java Version[The version of AgentScope-Java you are working on, e.g. 1.0.3, check your pom.xml dependency version or run
mvn dependency:tree | grep agentscope-parent:pom(only mac/linux)]Description
[Please describe the background, purpose, changes made, and how to test this PR]
Checklist
Please check the following items before code is ready to be reviewed.
mvn spotless:applymvn test)