[Feature] Expose typed model retry and fallback attempt events#2201
[Feature] Expose typed model retry and fallback attempt events#2201BG0527 wants to merge 11 commits into
Conversation
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
AgentScopeJavaBot
left a comment
There was a problem hiding this comment.
🤖 AI Review
This PR introduces typed model retry and fallback attempt events (ModelCallAttemptStartEvent, ModelCallAttemptEndEvent, ModelCallAttemptFailedEvent, ModelFallbackActivatedEvent) with a clean architecture: AttemptEventContext is injected into ExecutionConfig, the 5-arg applyTimeoutAndRetry() auto-detects it and delegates to the 9-arg version with tracker wiring, and ModelCallAttemptTracker emits lifecycle events on each resubscription. The ModelCallFailureClassifier provides structured error categorization with defense-in-depth sanitization. The design is sound and the test coverage is extensive (~3800 lines of tests). However, there is one significant logic bug (primaryAttemptCount never incremented), a secret-redaction gap in sanitizeMessage, and a few minor quality issues that should be addressed before merge.
(inline comments could not be attached — line numbers fell outside PR hunks. See archived report.)
AgentScopeJavaBot
left a comment
There was a problem hiding this comment.
🤖 AI Review
This PR introduces typed model retry and fallback attempt events (ModelCallAttemptStartEvent, ModelCallAttemptEndEvent, ModelCallAttemptFailedEvent, ModelFallbackActivatedEvent) with a clean architecture: AttemptEventContext is injected into ExecutionConfig, the 5-arg applyTimeoutAndRetry() auto-detects it and delegates to the 9-arg version with tracker wiring, and ModelCallAttemptTracker emits lifecycle events on each resubscription. The ModelCallFailureClassifier provides structured error categorization with defense-in-depth sanitization. The design is sound and the test coverage is extensive (~3800 lines of tests). However, there is one significant logic bug (primaryAttemptCount never incremented), a secret-redaction gap in sanitizeMessage, and a few minor quality issues that should be addressed before merge.
(inline comments could not be attached — line numbers fell outside PR hunks. See archived report.)
关联 issue
AgentScope-Java Version
v2.0.0
Description
Background
ReActAgent支持通过ExecutionConfig/ModelUtils进行模型重试,以及通过ReActAgent.Builder.fallbackModel(...)进行模型回退。然而streamEvents()仅暴露一个聚合的MODEL_CALL_START→MODEL_CALL_END边界,产品宿主无法从类型化运行时事件中获知:Root Cause
ModelUtils.applyTimeoutAndRetry(),不传 emitter,导致ModelCallAttemptTracker从未在真实调用链中被激活ReActAgent.modelCallStream()直接调用model.stream(),不经过applyTimeoutAndRetry,重试 tracker 不在调用链上ModelFallbackActivatedEvent的replyId和failedAttemptCount在modelForCall()中始终为 null 和 0ModelCallAttemptFailedEvent缺少nextAction字段,无法指示系统在失败后采取的行动(retry/fallback/fail)ModelCallAttemptEndEvent的usage永远为 null,未从ChatResponse中提取Fix
引入
AttemptEventContext作为运行时上下文对象,嵌入ExecutionConfig中由ReActAgent注入,5 参数版applyTimeoutAndRetry()自动从中读取 emitter 并激活 tracker,Provider 无需任何修改。Changed files:
1. 新增事件类型与枚举(Core Event 层)
ModelCallAttemptStartEvent— 模型调用尝试开始事件,含 replyId、attemptIndex、maxAttempts、provider、modelName、roleModelCallAttemptFailedEvent— 模型调用尝试失败事件,含 failureCategory、retryable、nextAction、errorCode、errorMessage、roleModelCallAttemptEndEvent— 模型调用尝试成功结束事件,含 usage(从 ChatResponse 提取)、latencyMs、roleModelFallbackActivatedEvent— 回退模型激活事件,含 replyId、failedAttemptCount、fromModel、toModelModelCallAttemptFailureCategory— 失败分类枚举:RATE_LIMIT、TIMEOUT、AUTHENTICATION、AUTHORIZATION、NETWORK、PROVIDER_5XX、INVALID_REQUEST、UNKNOWNModelCallAttemptRole— 角色枚举:PRIMARY、FALLBACKModelCallAttemptNextAction— 下一步动作枚举:RETRY、FALLBACK、FAILAgentEventType— 注册 4 个新事件类型2. 运行时集成与管道层(Core Model 层)
AttemptEventContext— 新增运行时上下文类,携带 emitter/replyId/role/hasFallback,非序列化ExecutionConfig— 新增attemptEventContext字段、getter、builder setter、mergeConfigs传播逻辑ModelCallAttemptTracker— 新增hasFallback参数、doOnNext提取 usage、computeNextAction()计算逻辑ModelCallFailureClassifier— 新增错误分类、重试判断、错误码/消息脱敏ModelUtils— 5 参数版applyTimeoutAndRetry自动读取AttemptEventContext;9 参数版传递hasFallback3. ReActAgent 集成
ReActAgent—modelCallStream()调用前注入AttemptEventContext;modelForCall()修复 replyId/failedAttemptCount 并为回退模型注入 FALLBACK role context;新增injectAttemptTracking/injectFallbackAttemptTracking/extractReplyId辅助方法4. 测试(66 个直接相关测试,全部通过)
ModelCallAttemptTrackerTest— tracker 单元测试ModelCallAttemptTrackerVerificationTest— 规格验证测试(429/5xx 重试、401/403 非重试、超时/网络重试、回退激活、secret 脱敏、JSON round-trip、向后兼容)ModelCallAttemptFeatureTest— nextAction 逻辑、AttemptEventContext 集成、usage 提取、5 参数版管道ReActAgentAttemptEventTest— 端到端测试(重试事件、回退激活、FALLBACK role、call() 路径、不重放 tool、HITL+回退、全部失败无 assistant 消息、context 传播)Checklist
mvn spotless:applymvn test) — 214 tests, 0 failures