mirror of
https://github.com/Ed1s0nZ/CyberStrikeAI.git
synced 2026-08-15 07:30:53 +02:00
126 lines
2.8 KiB
Go
126 lines
2.8 KiB
Go
package multiagent
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
"sync"
|
|
)
|
|
|
|
type einoPendingToolCalls struct {
|
|
conversationID string
|
|
progress func(eventType, message string, data interface{})
|
|
|
|
mu sync.Mutex
|
|
byID map[string]toolCallPendingInfo
|
|
queueByAgent map[string][]string
|
|
}
|
|
|
|
func newEinoPendingToolCalls(conversationID string, progress func(eventType, message string, data interface{})) *einoPendingToolCalls {
|
|
return &einoPendingToolCalls{
|
|
conversationID: conversationID,
|
|
progress: progress,
|
|
byID: make(map[string]toolCallPendingInfo),
|
|
queueByAgent: make(map[string][]string),
|
|
}
|
|
}
|
|
|
|
func (p *einoPendingToolCalls) Mark(tc toolCallPendingInfo) {
|
|
if p == nil || strings.TrimSpace(tc.ToolCallID) == "" {
|
|
return
|
|
}
|
|
p.mu.Lock()
|
|
defer p.mu.Unlock()
|
|
p.byID[tc.ToolCallID] = tc
|
|
p.queueByAgent[tc.EinoAgent] = append(p.queueByAgent[tc.EinoAgent], tc.ToolCallID)
|
|
}
|
|
|
|
func (p *einoPendingToolCalls) PopNextForAgent(agentName string) (toolCallPendingInfo, bool) {
|
|
if p == nil {
|
|
return toolCallPendingInfo{}, false
|
|
}
|
|
p.mu.Lock()
|
|
defer p.mu.Unlock()
|
|
q := p.queueByAgent[agentName]
|
|
for len(q) > 0 {
|
|
id := q[0]
|
|
q = q[1:]
|
|
p.queueByAgent[agentName] = q
|
|
if tc, ok := p.byID[id]; ok {
|
|
delete(p.byID, id)
|
|
return tc, true
|
|
}
|
|
}
|
|
return toolCallPendingInfo{}, false
|
|
}
|
|
|
|
func (p *einoPendingToolCalls) RemoveByID(toolCallID string) {
|
|
if p == nil || strings.TrimSpace(toolCallID) == "" {
|
|
return
|
|
}
|
|
p.mu.Lock()
|
|
defer p.mu.Unlock()
|
|
delete(p.byID, toolCallID)
|
|
}
|
|
|
|
func (p *einoPendingToolCalls) PopAny() (toolCallPendingInfo, bool) {
|
|
if p == nil {
|
|
return toolCallPendingInfo{}, false
|
|
}
|
|
p.mu.Lock()
|
|
defer p.mu.Unlock()
|
|
for id, tc := range p.byID {
|
|
delete(p.byID, id)
|
|
return tc, true
|
|
}
|
|
return toolCallPendingInfo{}, false
|
|
}
|
|
|
|
func (p *einoPendingToolCalls) Count() int {
|
|
if p == nil {
|
|
return 0
|
|
}
|
|
p.mu.Lock()
|
|
defer p.mu.Unlock()
|
|
return len(p.byID)
|
|
}
|
|
|
|
func (p *einoPendingToolCalls) FlushAsFailed(err error) {
|
|
if p == nil {
|
|
return
|
|
}
|
|
p.mu.Lock()
|
|
pendingSnapshot := make([]toolCallPendingInfo, 0, len(p.byID))
|
|
for _, tc := range p.byID {
|
|
pendingSnapshot = append(pendingSnapshot, tc)
|
|
}
|
|
p.byID = make(map[string]toolCallPendingInfo)
|
|
p.queueByAgent = make(map[string][]string)
|
|
p.mu.Unlock()
|
|
|
|
if p.progress == nil {
|
|
return
|
|
}
|
|
msg := ""
|
|
if err != nil {
|
|
msg = err.Error()
|
|
}
|
|
for _, tc := range pendingSnapshot {
|
|
toolName := tc.ToolName
|
|
if strings.TrimSpace(toolName) == "" {
|
|
toolName = "unknown"
|
|
}
|
|
p.progress("tool_result", fmt.Sprintf("工具结果 (%s)", toolName), map[string]interface{}{
|
|
"toolName": toolName,
|
|
"success": false,
|
|
"isError": true,
|
|
"result": msg,
|
|
"resultPreview": msg,
|
|
"toolCallId": tc.ToolCallID,
|
|
"conversationId": p.conversationID,
|
|
"einoAgent": tc.EinoAgent,
|
|
"einoRole": tc.EinoRole,
|
|
"source": "eino",
|
|
})
|
|
}
|
|
}
|