Skip to content

fix(multiagent): repair StreamingMeta index collisions on agentic streams - #286

Open
oierxjn wants to merge 1 commit into
Ed1s0nZ:mainfrom
oierxjn:fix/agentic-stream-block-index-repair
Open

fix(multiagent): repair StreamingMeta index collisions on agentic streams#286
oierxjn wants to merge 1 commit into
Ed1s0nZ:mainfrom
oierxjn:fix/agentic-stream-block-index-repair

Conversation

@oierxjn

@oierxjn oierxjn commented Aug 28, 2026

Copy link
Copy Markdown

Fixes #285

问题

部分模型网关(实测 Cloudflare Workers AI 经 new-api 中转)在并行 tool_calls 的流式响应中,会在两个工具调用之间插入空白文本帧。eino-ext acl/openaichunkConverter 会给该文本块分配与工具调用块相同的 StreamingMeta.Index(上游 bug,已报 cloudwego/eino-ext#975,修复 PR cloudwego/eino-ext#976),导致:

  1. schema.ConcatAgenticMessages 分组类型冲突报错(content block type mismatch
  2. eino ADK typedConsumeStream 吞掉该错误返回 nil 消息
  3. ShouldRetry 误判为 empty_model_output,确定性重试耗尽,整轮失败

单工具调用正常;并行调用(如 Agent 首轮常见的 skill + exec)在该类网关下必现。

修复

新增 agenticStreamBlockIndexRepairModel 包装器(与既有 streamToolCallIndexRepairModel 同一防御思路),挂在 newEinoAgenticChatModelFactory 的 OpenAI 兼容与 Claude 两条路径:

  • 逐帧检测跨块类型的 StreamingMeta.Index 冲突
  • 冲突块改编到负数 index(不与 converter 后续 index 相撞;同源分片映射一致,仍可正确聚合)
  • 内容完整保留;正常流原样透传

覆盖 eino 单代理 / Deep / Supervisor / Plan-Execute 主代理与子代理、failover 备用通道。

测试

  • 新增单测:用真实故障帧序列(文本 → 工具调用1 → 交错 "\n" → 工具调用2)验证修复前 concat 报类型冲突、修复后 2 个工具调用与文本完整聚合;另有"正常流不被改动"用例
  • go test ./internal/multiagent/ 全部通过
  • 已在生产环境(Debian + 上述网关)实测:修复前必现失败的操作修复后正常

备注

本补丁为框架边界防御。待 eino-ext 上游修复发版、本项目升级依赖后,该包装器可移除(保留亦无副作用)。

…eams

Some providers (e.g. Cloudflare Workers AI gateways) interleave text
chunks between parallel tool-call chunks in one SSE stream. The chunk
converter in eino-ext acl/openai assigns such a text block the same
StreamingMeta.Index as the preceding tool-call block, so
schema.ConcatAgenticMessages fails with a block type mismatch. The ADK
retry checker swallows that error and sees a nil message, surfacing as a
misleading empty-model-output rejection and a deterministic
retry-exhausted failure on the first parallel tool call round.

Wrap agentic chat models (OpenAI-compatible and Claude paths) with a
stream repair layer that reassigns colliding blocks to fresh negative
indices, keeping every concat group single-typed while preserving all
block content. Valid streams pass through untouched.

Root cause reported upstream: cloudwego/eino-ext#975 (fix PR:
cloudwego/eino-ext#976). This wrapper is a defensive boundary fix and
can be removed after the eino-ext fix lands in a released dependency.

Fixes Ed1s0nZ#285
@oierxjn
oierxjn marked this pull request as ready for review August 28, 2026 09:46
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.

fix: agentic 流式路径在并行工具调用时因 provider 交错文本帧聚合失败,误报 empty_model_output

1 participant