mirror of
https://github.com/Ed1s0nZ/CyberStrikeAI.git
synced 2026-08-15 07:30:53 +02:00
104 lines
2.3 KiB
Go
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
|
|
}
|