Github开源生信云平台 DEMO
Emit
Searched for text func recordFileRead (go-project · gobrave/internal/agent/tool/coder/**), 1 result
func recordFileRead
go-project
gobrave/internal/agent/tool/coder/**
Read , lines 1 to 45
是的,目前子 Agent 的 Emit 完全不会落库。
子 Agent 在 agentTool.runTask 里使用的是独立 Runtime:
agentTool.runTask
answer, err := sub.Run(ctx, agent.Request{...}, agent.NewStandaloneRuntime(nil))
而 standaloneRuntime.Emit 的实现是:
standaloneRuntime.Emit
func (r *standaloneRuntime) Emit(ctx context.Context, event StreamEvent) error { if r.handler != nil { return r.handler(ctx, event) } return nil // handler 为 nil → 直接丢弃 }
对比父 Agent 的 taskRuntime.Emit:
taskRuntime.Emit
if isBlockEvent(event.Type) { r.svc.emitEvent(ctx, r.taskID, EventStream, event) // 落库 + 广播 } else { r.svc.broadcastEvent(ctx, r.taskID, EventStream, event) }
所以两条链路是:
streamOnce / executeTools 里所有事件都走这个 no-op:
streamOnce
executeTools
StreamEventText
StreamEventReasoningDelta
StreamEventReasoning
StreamEventMessage
StreamEventToolCall
StreamEventToolResult
StreamEventDone
父 Agent 在收到 agent 工具结果后,会通过父 Runtime 下发一条 StreamEventToolResult:
agent
c.emitToolResult(ctx, rt, call, results[i]) // rt 是父 Agent 的 taskRuntime
所以 DB 里只能看到:
tool_call
tool_result
子 Agent 的思考过程、内部 glob/grep/view 调用、中间轮次全部不可见。
权限桥接用的是父 RuntimePrepareToolContext 复用 a.toolContext(req, rt),子 Agent 工具若调用 RequirePermission,会走父 Runtime 并可能触发 permission 事件落库。但子 Agent 只有 glob/grep/ls/view/sourcegraph,都不请求权限,所以实际不会触发。
PrepareToolContext
a.toolContext(req, rt)
RequirePermission
permission
glob/grep/ls/view/sourcegraph
view 的 recordFileRead 不落库internal/agent/tool/coder/file.go 里只是进程内的 map[string]fileRecord + mutex,用于 edit/write 前的读取时间校验,不涉及数据库。
view
recordFileRead
internal/agent/tool/coder/file.go
map[string]fileRecord
需要把 NewStandaloneRuntime(nil) 换成能持久化的 Runtime,并且通常要先给子 Agent 建子会话(即上次说的 ParentSessionID 接线)。否则即使 Emit 有 handler,也没有 taskID / sessionID 可以挂载事件。
NewStandaloneRuntime(nil)
ParentSessionID
taskID
sessionID