mirror of
https://github.com/Ed1s0nZ/CyberStrikeAI.git
synced 2026-03-31 00:09:29 +02:00
Add files via upload
This commit is contained in:
@@ -44,11 +44,20 @@ func (h *AgentHandler) MultiAgentLoopStream(c *gin.Context) {
|
||||
|
||||
c.Header("X-Accel-Buffering", "no")
|
||||
|
||||
// 用于在 sendEvent 中判断是否为用户主动停止导致的取消。
|
||||
// 注意:baseCtx 会在后面创建;该变量用于闭包提前捕获引用。
|
||||
var baseCtx context.Context
|
||||
|
||||
clientDisconnected := false
|
||||
sendEvent := func(eventType, message string, data interface{}) {
|
||||
if clientDisconnected {
|
||||
return
|
||||
}
|
||||
// 用户主动停止时,Eino 可能仍会并发上报 eventType=="error"。
|
||||
// 为避免 UI 看到“取消错误 + cancelled 文案”两条回复,这里直接丢弃取消对应的 error。
|
||||
if eventType == "error" && baseCtx != nil && errors.Is(context.Cause(baseCtx), ErrTaskCancelled) {
|
||||
return
|
||||
}
|
||||
select {
|
||||
case <-c.Request.Context().Done():
|
||||
clientDisconnected = true
|
||||
@@ -135,7 +144,6 @@ func (h *AgentHandler) MultiAgentLoopStream(c *gin.Context) {
|
||||
)
|
||||
|
||||
if runErr != nil {
|
||||
h.logger.Error("Eino DeepAgent 执行失败", zap.Error(runErr))
|
||||
cause := context.Cause(baseCtx)
|
||||
if errors.Is(cause, ErrTaskCancelled) {
|
||||
taskStatus = "cancelled"
|
||||
@@ -153,6 +161,7 @@ func (h *AgentHandler) MultiAgentLoopStream(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
h.logger.Error("Eino DeepAgent 执行失败", zap.Error(runErr))
|
||||
taskStatus = "failed"
|
||||
h.tasks.UpdateTaskStatus(conversationID, taskStatus)
|
||||
errMsg := "执行失败: " + runErr.Error()
|
||||
|
||||
62
internal/multiagent/no_nested_task.go
Normal file
62
internal/multiagent/no_nested_task.go
Normal file
@@ -0,0 +1,62 @@
|
||||
package multiagent
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
"github.com/cloudwego/eino/adk"
|
||||
"github.com/cloudwego/eino/components/tool"
|
||||
)
|
||||
|
||||
// noNestedTaskMiddleware 禁止在已经处于 task(sub-agent) 执行链中再次调用 task,
|
||||
// 避免子代理再次委派子代理造成的无限委派/递归。
|
||||
//
|
||||
// 通过在 ctx 中设置临时标记来实现嵌套检测:外层 task 调用会先标记 ctx,
|
||||
// 子代理内再调用 task 时会命中该标记并拒绝。
|
||||
type noNestedTaskMiddleware struct {
|
||||
adk.BaseChatModelAgentMiddleware
|
||||
}
|
||||
|
||||
type nestedTaskCtxKey struct{}
|
||||
|
||||
func newNoNestedTaskMiddleware() adk.ChatModelAgentMiddleware {
|
||||
return &noNestedTaskMiddleware{}
|
||||
}
|
||||
|
||||
func (m *noNestedTaskMiddleware) WrapInvokableToolCall(
|
||||
ctx context.Context,
|
||||
endpoint adk.InvokableToolCallEndpoint,
|
||||
tCtx *adk.ToolContext,
|
||||
) (adk.InvokableToolCallEndpoint, error) {
|
||||
if tCtx == nil || strings.TrimSpace(tCtx.Name) == "" {
|
||||
return endpoint, nil
|
||||
}
|
||||
// Deep 内置 task 工具名固定为 "task";为兼容可能的大小写/空白,仅做不区分大小写匹配。
|
||||
if !strings.EqualFold(strings.TrimSpace(tCtx.Name), "task") {
|
||||
return endpoint, nil
|
||||
}
|
||||
|
||||
// 已在 task 执行链中:拒绝继续委派,直接报错让上层快速终止。
|
||||
if ctx != nil {
|
||||
if v, ok := ctx.Value(nestedTaskCtxKey{}).(bool); ok && v {
|
||||
return func(ctx context.Context, argumentsInJSON string, opts ...tool.Option) (string, error) {
|
||||
// Important: return a tool result text (not an error) to avoid hard-stopping the whole multi-agent run.
|
||||
// The nested task is still prevented from spawning another sub-agent, so recursion is avoided.
|
||||
_ = argumentsInJSON
|
||||
_ = opts
|
||||
return "Nested task delegation is forbidden (already inside a sub-agent delegation chain) to avoid infinite delegation. Please continue the work using the current agent's tools.", nil
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
|
||||
// 标记当前 task 调用链,确保子代理内的再次 task 调用能检测到嵌套。
|
||||
return func(ctx context.Context, argumentsInJSON string, opts ...tool.Option) (string, error) {
|
||||
ctx2 := ctx
|
||||
if ctx2 == nil {
|
||||
ctx2 = context.Background()
|
||||
}
|
||||
ctx2 = context.WithValue(ctx2, nestedTaskCtxKey{}, true)
|
||||
return endpoint(ctx2, argumentsInJSON, opts...)
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -252,7 +252,11 @@ func RunDeepAgent(
|
||||
WithoutGeneralSubAgent: ma.WithoutGeneralSubAgent,
|
||||
WithoutWriteTodos: ma.WithoutWriteTodos,
|
||||
MaxIteration: deepMaxIter,
|
||||
Handlers: []adk.ChatModelAgentMiddleware{mainSumMw},
|
||||
// 防止 sub-agent 再调用 task(再委派 sub-agent),形成无限委派链。
|
||||
Handlers: []adk.ChatModelAgentMiddleware{
|
||||
newNoNestedTaskMiddleware(),
|
||||
mainSumMw,
|
||||
},
|
||||
ToolsConfig: adk.ToolsConfig{
|
||||
ToolsNodeConfig: compose.ToolsNodeConfig{
|
||||
Tools: mainTools,
|
||||
|
||||
Reference in New Issue
Block a user