cloudwego / cloudwego/eino

fix(adk): EmitInternalEvents has no effect for Agentic path (TypedAgent[*schema.AgenticMessage])

Open
#1,055 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
Go
Stars
13k
Forks
1.1k
Avg merge
4h 6m
Merged PRs (30d)
41

Description

**Describe the bug**

`ToolsConfig.EmitInternalEvents` 在 Agentic 路径(`*schema.AgenticMessage`)下无效。子 Agent 的内部事件(模型输出、工具调用、工具结果)不会透出到父 Agent 的事件流中。

根本原因有两层:

1. **`buildAgenticReActRunFunc` 未注入 `EmitInternalEvents` 的 event generator**:在 `adk/chatmodel.go` 中,Message 路径的 `buildReActRunFunc`(第 1199 行)在 `EmitInternalEvents` 为 true 时注入 `withAgentToolEventGenerator`:

```go
if a.toolsConfig.EmitInternalEvents {
runOpts = append(runOpts, compose.WithToolsNodeOption(compose.WithToolOption(withAgentToolEventGenerator(mp.generator))))
}
```

然而 Agentic 路径的 `buildAgenticReActRunFunc`(第 1330-1334 行)只注入了 `withAgentToolEnableStreaming`,**完全没有** `EmitInternalEvents` 的处理分支。

2. **类型不兼容**:即使修复了第一层问题,`withAgentToolEventGenerator` 接受的参数类型是 `*AsyncGenerator[*AgentEvent]`,其中 `*AgentEvent = *TypedAgentEvent[*schema.Message]`。而 Agentic 路径使用的是 `*AsyncGenerator[*TypedAgentEvent[*schema.AgenticMessage]]`,两者类型不兼容。同样,`agent_tool.go` 第 242 行的事件转发逻辑 `any(event).(*AgentEvent)` 对 Agentic 事件会始终失败,因为 `*TypedAgentEvent[*schema.AgenticMessage]` ≠ `*AgentEvent`。

**To Reproduce**

1. 使用 Agentic 路径创建一个带有子 Agent 的 Deep Agent,设置 `EmitInternalEvents: true`
2. 运行 Agent,触发子 Agent 委派任务
3. 观察事件流中子 Agent 的内部事件(推理、工具调用)完全缺失——仅返回最终结果作为工具结果

示例代码:

```go
package main

import (
"context"
"fmt"

"github.com/cloudwego/eino/adk"
"github.com/cloudwego/eino/adk/prebuilt/deep"
"github.com/cloudwego/eino/components/tool"
"github.com/cloudwego/eino/schema"
)

func main() {
ctx := context.Background()

// 创建 Agentic 子 Agent
subAgent, err := adk.NewTypedChatModelAgent[*schema.AgenticMessage](ctx, &adk.TypedChatModelAgentConfig[*schema.AgenticMessage]{
Name: "web_searcher",
Description: "Search the web for real-time information",
Instruction: "You are a web search expert.",
Model: agenticModel, // model.AgenticModel
ToolsConfig: adk.ToolsConfig{Tools: []tool.BaseTool{searchTool}},
})
if err != nil {
panic(err)
}

// 创建 Agentic Deep Agent,启用 EmitInternalEvents
agent, err := deep.NewTyped[*schema.AgenticMessage](ctx, &deep.TypedConfig[*schema.AgenticMessage]{
ChatModel: agenticModel,
ToolsConfig: adk.ToolsConfig{
EmitInternalEvents: true, // 在 Agentic 路径下无效
},
SubAgents: []adk.TypedAgent[*schema.AgenticMessage]{subAgent},
})
if err != nil {
panic(err)
}

// 运行并观察事件流
runner := adk.NewTypedRunner[*schema.AgenticMessage](ctx, adk.TypedRunnerConfig[*schema.AgenticMessage]{
Agent: agent,
EnableStreaming: true,
})
iter := runner.Run(ctx, []*schema.AgenticMessage{schema.UserAgenticMessage("搜索最新新闻")})
for {
event, ok := iter.Next()
if !ok {
break
}
// 期望能看到子 Agent 的内部事件,但实际只有最终结果
fmt.Println(event)
}
}
```

对比 Message 路径下 `EmitInternalEvents: true` 可正常工作,子 Agent 事件能正确透出。

**Expected behavior**

`EmitInternalEvents: true` 在 Agentic 路径下应与 Message 路径行为一致。启用后,子 Agent 的内部事件(模型输出、工具调用、工具结果)应透出到父 Agent 的 `AsyncGenerator`,以便通过 Runner 实时推送给终端用户。

**Screenshots**

**Version:**

eino v0.9.2

**Environment:**

```
go version go1.24.3 linux/amd64
```

**Additional context**

修复可能需要:

1. 新增 Agentic 兼容的 event generator 注入机制(例如新增 `withTypedAgentToolEventGenerator[M]` 或类似函数)
2. 在 `buildAgenticReActRunFunc` 中补充 `EmitInternalEvents` 处理分支
3. 更新 `agent_tool.go` 的事件转发逻辑,支持 `*TypedAgentEvent[*schema.AgenticMessage]` 类型

注意:`ToolsConfig` 中 `EmitInternalEvents` 字段的文档描述为通用的 agent tool 事件透出,但实现仅覆盖了 Message 路径。Deep Agent 的 `task_tool.go` 最终委托给 `agent_tool.go` 的 `typedAgentTool[M].InvokableRun`,因此修复 `agent_tool.go` 是关键。

Contributor guide

Open the contributing guide

Research direction

Start in adk/chatmodel.go by comparing buildAgenticReActRunFunc with buildReActRunFunc, then trace event forwarding in agent_tool.go, especially typed event handling. Verify the Agentic path with EmitInternalEvents enabled using the reproduction, and consider the work complete when child model, tool-call, and tool-result events reach the parent AsyncGenerator as they do on the Message path.

Written by the indexing model from the issue text.

Assessment

Tech stack
go
Domain
ai, backend-api-design
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
58/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.