Skip to content

fix(harness): unify compaction overflow recovery and redact session log media sources - #3568

Open
dargoner wants to merge 15 commits into
agentscope-ai:mainfrom
dargoner:fix/compaction-recovery-redact-events
Open

dargoner wants to merge 15 commits into
agentscope-ai:mainfrom
dargoner:fix/compaction-recovery-redact-events

Conversation

@dargoner

Copy link
Copy Markdown
Contributor

AgentScope-Java Version

2.1.0-SNAPSHOT (based on main @ 5f7f8e6)

Description

Background

Hardening work on the context-compaction pipeline surfaced three gaps in overflow recovery and observability:

  1. Divergent recovery paths. Normal compaction and the emergency context-overflow retry used different code paths. The emergency retry could commit the compaction candidate history before the retry succeeded, and when the retry failed, the retry error masked the original overflow cause.
  2. Session log media leakage. SessionRecorder redacted top-level text, but media embedded inside ToolResult blocks (base64 payloads, inline file bytes) was still written into the session log request/prepared events.
  3. Weak lifecycle observability. Compaction start/end events were not emitted as consistent pairs across the normal and emergency paths, and cancellation between the two paths was not isolated.

Changes

  • Unify compaction overflow recovery (CompactionMiddleware, ConversationCompactor, HarnessAgent): one recovery path for normal and emergency compaction; an emergency retry no longer commits candidate history early; when the retry fails, the first overflow is preserved as the primary cause via initCause.
  • Redact session log media sources (SessionRecorder): request/prepared events recursively redact media nested inside ToolResult blocks while preserving the surrounding structure.
  • Compaction lifecycle events (HarnessAgent, CompactionMiddleware): start/end event pairs are emitted consistently with cancel isolation hardened; failure logs are redacted.
  • Memory middleware follow-ups (MemoryFlushMiddleware, MemoryMaintenanceMiddleware, MemoryFlushManager): log redaction in failure paths.
  • Docs: session-log.md, context.md and memory.md (EN/ZH) updated for the new event semantics and log fields.

Tests

  • Core: ReActSessionLogTest 5 → 7 cases (media-source redaction).
  • Harness: HarnessAgentTest 55 → 57, ConversationCompactorTest 8 → 19, CompactionMiddlewareTest 11 → 23.
  • Full agentscope-core + agentscope-harness suites: BUILD SUCCESS (harness 1270 tests, 0 failures; the 18 skips are Windows/docker environment markers).
  • mvn spotless:check passes; docs npm test / npm run check pass.

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

- 移除 HarnessAgent.wrappedCall 的紧急恢复分支,所有恢复统一走
  CompactionMiddleware.overflowRecovery() companion,保证 call() 与
  streamEvents() 在有无 session log 时都仅重试一次。
- 恢复门控改为视图缩减检测 + 并发/提交保护:durable 含 synthetic 时
  仍可重试,但只更新可提交的 durable 历史。
- compaction/start 与 compaction/end 事件不再携带 inputMessages 与
  原始异常消息;end 增加 durationMs,failed 增加 errorType。
- ConversationCompactor 触发压缩时发射 context_compaction_started/finished 自定义事件
  (compactionId/mode/终态与前后计数),取消兜底经 doFinally + markSettled CAS 单次认领,
  终态补写为纯内存追加、由所属调用的受管理 flush 持久化
- CompactionMiddleware 在 onModelCall 边界透传 AgentEventEmitter,EMERGENCY 溢出恢复
  路径标记 mode=EMERGENCY
- HarnessAgent 三个调用生命周期 wrapper(wrappedCall/wrappedStreamEvents/deprecated
  wrappedStream)最外层 cancelOn(boundedElastic):取消行走(含压缩补写与 recorder
  受管理清理)移出调用线程,保持「补写先于受管理关闭」顺序
- 测试:受控持锁集成测试(真实 run.cancel 即时返回 + durable start/end 恰好一对,
  移除 cancelOn 的反向验证在阻塞断言处失败);获取前取消测试增加 commitEntered/
  commitExited 屏障与中断耐受门闸,消除调度竞态
recoverFromOverflow 此前在重试请求通过最终请求 preparer 校验(预算、工具配对)
之前就把 emergency 压缩候选写入 AgentState,校验拒绝时脏历史已经落库。
现改为只把缩减后的请求视图交给下游重试,持久历史仍由最终 preparer 校验后的
提交点负责;新增真实链路回归:首次 overflow → emergency 摘要成功 → 最终
preparer 拒绝 → 断言历史未被替换、不再触达 provider。
单次恢复重试失败时,原错误继续作为终止信号,首次 overflow 通过
cause 关联(已有 cause 时改用 suppressed),使首次 provider 溢出不
被重试自身错误覆盖;取消、中断与 fatal 错误不做改写,保留 Reactor
取消语义。补充二次溢出主因、取消不改写、应急摘要失败仍报首次
overflow 三组回归。
@codecov

codecov Bot commented Oct 14, 2026

Copy link
Copy Markdown

dargoner and others added 6 commits October 16, 2026 18:41
…nts' into fix/compaction-recovery-redact-events
The cancel assertion holds the recorder monitor and only fails on a real
storage block; a 5s wall-clock wait also tripped when the canceller thread
was scheduled late on a saturated ubuntu runner.
@dargoner
dargoner force-pushed the fix/compaction-recovery-redact-events branch from f286402 to 53e24d2 Compare October 18, 2026 13:13

This branch has not been deployed

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants