mirror of
https://github.com/Ed1s0nZ/CyberStrikeAI.git
synced 2026-07-14 07:57:26 +02:00
Add files via upload
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
package multiagent
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const toolSearchToolName = "tool_search"
|
||||
|
||||
// HitlExemptMetaTools 为编排/元工具:不直接执行攻击动作,但会阻塞 agent 控制流。
|
||||
// tool_search 必须免审批,否则其 HITL 拒绝结果与 Eino toolsearch 中间件不兼容(会硬崩 ChatModel)。
|
||||
var HitlExemptMetaTools = []string{
|
||||
toolSearchToolName,
|
||||
"skill",
|
||||
"task",
|
||||
"write_todos",
|
||||
"transfer_to_agent",
|
||||
"exit",
|
||||
"TaskCreate",
|
||||
"TaskGet",
|
||||
"TaskUpdate",
|
||||
"TaskList",
|
||||
}
|
||||
|
||||
// IsToolSearchTool reports whether name is the Eino dynamictool tool_search meta-tool.
|
||||
func IsToolSearchTool(name string) bool {
|
||||
return strings.EqualFold(strings.TrimSpace(name), toolSearchToolName)
|
||||
}
|
||||
|
||||
// MergeHitlExemptMetaTools unions configured whitelist with built-in meta-tool exemptions.
|
||||
func MergeHitlExemptMetaTools(configured []string) []string {
|
||||
merged := make([]string, 0, len(configured)+len(HitlExemptMetaTools))
|
||||
seen := make(map[string]struct{}, len(configured)+len(HitlExemptMetaTools))
|
||||
add := func(name string) {
|
||||
n := strings.ToLower(strings.TrimSpace(name))
|
||||
if n == "" {
|
||||
return
|
||||
}
|
||||
if _, ok := seen[n]; ok {
|
||||
return
|
||||
}
|
||||
seen[n] = struct{}{}
|
||||
merged = append(merged, strings.TrimSpace(name))
|
||||
}
|
||||
for _, t := range configured {
|
||||
add(t)
|
||||
}
|
||||
for _, t := range HitlExemptMetaTools {
|
||||
add(t)
|
||||
}
|
||||
return merged
|
||||
}
|
||||
|
||||
type toolSearchHitlRejectPayload struct {
|
||||
SelectedTools []string `json:"selectedTools"`
|
||||
HitlRejected bool `json:"_hitlRejected"`
|
||||
Reason string `json:"reason"`
|
||||
}
|
||||
|
||||
// HitlRejectToolResult returns a tool result body safe for downstream consumers.
|
||||
// tool_search must stay JSON-shaped so toolsearch.extractSelectedTools does not terminate the graph.
|
||||
func HitlRejectToolResult(toolName, reason string) string {
|
||||
reason = strings.TrimSpace(reason)
|
||||
if !IsToolSearchTool(toolName) {
|
||||
if reason == "" {
|
||||
reason = "rejected by reviewer"
|
||||
}
|
||||
return fmt.Sprintf("[HITL Reject] Tool '%s' was rejected by reviewer. Reason: %s\nPlease adjust parameters/plan and continue without this call.",
|
||||
strings.TrimSpace(toolName), reason)
|
||||
}
|
||||
payload := toolSearchHitlRejectPayload{
|
||||
SelectedTools: []string{},
|
||||
HitlRejected: true,
|
||||
Reason: reason,
|
||||
}
|
||||
if payload.Reason == "" {
|
||||
payload.Reason = "tool_search rejected by reviewer; no dynamic tools unlocked"
|
||||
}
|
||||
out, err := json.Marshal(payload)
|
||||
if err != nil {
|
||||
return `{"selectedTools":[],"_hitlRejected":true,"reason":"tool_search rejected by reviewer"}`
|
||||
}
|
||||
return string(out)
|
||||
}
|
||||
Reference in New Issue
Block a user