Files
CyberStrikeAI/internal/multiagent/eino_turn_loop_event_bridge.go
T
2026-08-15 02:08:52 +08:00

104 lines
2.3 KiB
Go

package multiagent
import (
"context"
"errors"
"strings"
"sync/atomic"
"github.com/cloudwego/eino/adk"
"github.com/cloudwego/eino/schema"
)
type einoTurnLoopEventBridge struct {
conversationID string
orchestration string
progress func(eventType, message string, data interface{})
gen *adk.AsyncGenerator[*adk.AgentEvent]
forwardedErr atomic.Bool
}
func newEinoTurnLoopEventBridge(
conversationID string,
orchestration string,
progress func(eventType, message string, data interface{}),
gen *adk.AsyncGenerator[*adk.AgentEvent],
) *einoTurnLoopEventBridge {
return &einoTurnLoopEventBridge{
conversationID: conversationID,
orchestration: orchestration,
progress: progress,
gen: gen,
}
}
func (b *einoTurnLoopEventBridge) OnAgentEvents(
_ context.Context,
tc *adk.TurnContext[EinoTurnLoopItem, *schema.Message],
events *adk.AsyncIterator[*adk.AgentEvent],
) error {
for {
ev, ok := events.Next()
if !ok {
return nil
}
if ev == nil {
continue
}
if ev.Err != nil && isEinoTurnLoopPreemptCancel(tc, ev.Err) {
b.emitPreempted()
continue
}
if b.gen != nil {
b.gen.Send(ev)
}
if ev.Err != nil {
b.forwardedErr.Store(true)
return ev.Err
}
}
}
func (b *einoTurnLoopEventBridge) ForwardedError() bool {
if b == nil {
return false
}
return b.forwardedErr.Load()
}
func (b *einoTurnLoopEventBridge) emitPreempted() {
if b == nil || b.progress == nil {
return
}
b.progress("progress", "Eino TurnLoop 已在安全点切换到用户补充后的下一轮。", map[string]interface{}{
"conversationId": b.conversationID,
"source": "eino",
"orchestration": b.orchestration,
"kind": "turn_loop_preempted",
})
}
func isEinoTurnLoopPreemptCancel(tc *adk.TurnContext[EinoTurnLoopItem, *schema.Message], err error) bool {
if tc == nil || err == nil {
return false
}
var cancelErr *adk.CancelError
if !errors.As(err, &cancelErr) {
return false
}
select {
case <-tc.Preempted:
return true
default:
return false
}
}
func einoTurnLoopInterruptTimelineSummary(note string) string {
note = strings.TrimSpace(note)
if note == "" {
return "用户选择「中断并继续」,未填写说明;已推入 Eino TurnLoop 并等待安全点续跑。"
}
return "用户中断说明(Eino TurnLoop 原生续跑):\n\n" + note
}