Skip to content

[Feature] Expose typed model retry and fallback attempt events#2201

Open
BG0527 wants to merge 11 commits into
agentscope-ai:mainfrom
BG0527:Expose-typed-events
Open

[Feature] Expose typed model retry and fallback attempt events#2201
BG0527 wants to merge 11 commits into
agentscope-ai:mainfrom
BG0527:Expose-typed-events

Conversation

@BG0527

@BG0527 BG0527 commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

关联 issue

AgentScope-Java Version

v2.0.0

Description

Background

ReActAgent 支持通过 ExecutionConfig / ModelUtils 进行模型重试,以及通过 ReActAgent.Builder.fallbackModel(...) 进行模型回退。然而 streamEvents() 仅暴露一个聚合的 MODEL_CALL_STARTMODEL_CALL_END 边界,产品宿主无法从类型化运行时事件中获知:

  • 哪个 provider/model 完成了成功响应
  • 主模型是否被重试
  • 回退是否被激活
  • 发生了多少次尝试
  • 失败是限流、超时、认证、网络还是 5xx
  • 哪次尝试消耗了报告的 usage/latency

Root Cause

  1. Provider 实现均调用 5 参数版 ModelUtils.applyTimeoutAndRetry(),不传 emitter,导致 ModelCallAttemptTracker 从未在真实调用链中被激活
  2. ReActAgent.modelCallStream() 直接调用 model.stream(),不经过 applyTimeoutAndRetry,重试 tracker 不在调用链上
  3. ModelFallbackActivatedEventreplyIdfailedAttemptCountmodelForCall() 中始终为 null 和 0
  4. ModelCallAttemptFailedEvent 缺少 nextAction 字段,无法指示系统在失败后采取的行动(retry/fallback/fail)
  5. ModelCallAttemptEndEventusage 永远为 null,未从 ChatResponse 中提取

Fix

引入 AttemptEventContext 作为运行时上下文对象,嵌入 ExecutionConfig 中由 ReActAgent 注入,5 参数版 applyTimeoutAndRetry() 自动从中读取 emitter 并激活 tracker,Provider 无需任何修改。

Changed files:

1. 新增事件类型与枚举(Core Event 层)

  • ModelCallAttemptStartEvent — 模型调用尝试开始事件,含 replyId、attemptIndex、maxAttempts、provider、modelName、role
  • ModelCallAttemptFailedEvent — 模型调用尝试失败事件,含 failureCategory、retryable、nextAction、errorCode、errorMessage、role
  • ModelCallAttemptEndEvent — 模型调用尝试成功结束事件,含 usage(从 ChatResponse 提取)、latencyMs、role
  • ModelFallbackActivatedEvent — 回退模型激活事件,含 replyId、failedAttemptCount、fromModel、toModel
  • ModelCallAttemptFailureCategory — 失败分类枚举:RATE_LIMIT、TIMEOUT、AUTHENTICATION、AUTHORIZATION、NETWORK、PROVIDER_5XX、INVALID_REQUEST、UNKNOWN
  • ModelCallAttemptRole — 角色枚举:PRIMARY、FALLBACK
  • ModelCallAttemptNextAction — 下一步动作枚举:RETRY、FALLBACK、FAIL
  • AgentEventType — 注册 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 参数版传递 hasFallback

3. ReActAgent 集成

  • ReActAgentmodelCallStream() 调用前注入 AttemptEventContextmodelForCall() 修复 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

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

@BG0527 BG0527 requested a review from a team July 14, 2026 13:46
@codecov

codecov Bot commented Jul 14, 2026

Copy link
Copy Markdown

@AgentScopeJavaBot AgentScopeJavaBot added enhancement New feature or request area/core/model Model providers and formatters area/core/agent Agent runtime, pipeline, hooks, plan labels Jul 15, 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

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 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

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.)

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 area/core/model Model providers and formatters enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Expose typed model retry and fallback attempt events

2 participants