mirror of
https://github.com/Ed1s0nZ/CyberStrikeAI.git
synced 2026-08-07 19:38:41 +02:00
Add files via upload
This commit is contained in:
+28
-20
@@ -22,6 +22,7 @@ type Config struct {
|
|||||||
OpenAI OpenAIConfig `yaml:"openai"`
|
OpenAI OpenAIConfig `yaml:"openai"`
|
||||||
FOFA FofaConfig `yaml:"fofa,omitempty" json:"fofa,omitempty"`
|
FOFA FofaConfig `yaml:"fofa,omitempty" json:"fofa,omitempty"`
|
||||||
Agent AgentConfig `yaml:"agent"`
|
Agent AgentConfig `yaml:"agent"`
|
||||||
|
Hitl HitlConfig `yaml:"hitl,omitempty" json:"hitl,omitempty"`
|
||||||
Security SecurityConfig `yaml:"security"`
|
Security SecurityConfig `yaml:"security"`
|
||||||
Database DatabaseConfig `yaml:"database"`
|
Database DatabaseConfig `yaml:"database"`
|
||||||
Auth AuthConfig `yaml:"auth"`
|
Auth AuthConfig `yaml:"auth"`
|
||||||
@@ -39,21 +40,21 @@ type Config struct {
|
|||||||
type MultiAgentConfig struct {
|
type MultiAgentConfig struct {
|
||||||
Enabled bool `yaml:"enabled" json:"enabled"`
|
Enabled bool `yaml:"enabled" json:"enabled"`
|
||||||
RobotUseMultiAgent bool `yaml:"robot_use_multi_agent" json:"robot_use_multi_agent"` // 为 true 时钉钉/飞书/企微机器人走 Eino 多代理
|
RobotUseMultiAgent bool `yaml:"robot_use_multi_agent" json:"robot_use_multi_agent"` // 为 true 时钉钉/飞书/企微机器人走 Eino 多代理
|
||||||
BatchUseMultiAgent bool `yaml:"batch_use_multi_agent" json:"batch_use_multi_agent"` // 为 true 时批量任务队列中每子任务走 Eino 多代理
|
BatchUseMultiAgent bool `yaml:"batch_use_multi_agent" json:"batch_use_multi_agent"` // 为 true 时批量任务队列中每子任务走 Eino 多代理
|
||||||
// Orchestration 已弃用:保留仅兼容旧版 config.yaml;编排由聊天/WebShell 请求体 orchestration 决定,未传时按 deep。
|
// Orchestration 已弃用:保留仅兼容旧版 config.yaml;编排由聊天/WebShell 请求体 orchestration 决定,未传时按 deep。
|
||||||
Orchestration string `yaml:"orchestration,omitempty" json:"orchestration,omitempty"`
|
Orchestration string `yaml:"orchestration,omitempty" json:"orchestration,omitempty"`
|
||||||
MaxIteration int `yaml:"max_iteration" json:"max_iteration"` // 主代理 / 执行器最大推理轮次(Deep、Supervisor、plan_execute 的 Executor)
|
MaxIteration int `yaml:"max_iteration" json:"max_iteration"` // 主代理 / 执行器最大推理轮次(Deep、Supervisor、plan_execute 的 Executor)
|
||||||
// PlanExecuteLoopMaxIterations plan_execute 模式下 execute↔replan 外层循环上限;0 表示用 Eino 默认 10。
|
// PlanExecuteLoopMaxIterations plan_execute 模式下 execute↔replan 外层循环上限;0 表示用 Eino 默认 10。
|
||||||
PlanExecuteLoopMaxIterations int `yaml:"plan_execute_loop_max_iterations,omitempty" json:"plan_execute_loop_max_iterations,omitempty"`
|
PlanExecuteLoopMaxIterations int `yaml:"plan_execute_loop_max_iterations,omitempty" json:"plan_execute_loop_max_iterations,omitempty"`
|
||||||
SubAgentMaxIterations int `yaml:"sub_agent_max_iterations" json:"sub_agent_max_iterations"`
|
SubAgentMaxIterations int `yaml:"sub_agent_max_iterations" json:"sub_agent_max_iterations"`
|
||||||
WithoutGeneralSubAgent bool `yaml:"without_general_sub_agent" json:"without_general_sub_agent"`
|
WithoutGeneralSubAgent bool `yaml:"without_general_sub_agent" json:"without_general_sub_agent"`
|
||||||
WithoutWriteTodos bool `yaml:"without_write_todos" json:"without_write_todos"`
|
WithoutWriteTodos bool `yaml:"without_write_todos" json:"without_write_todos"`
|
||||||
OrchestratorInstruction string `yaml:"orchestrator_instruction" json:"orchestrator_instruction"`
|
OrchestratorInstruction string `yaml:"orchestrator_instruction" json:"orchestrator_instruction"`
|
||||||
// OrchestratorInstructionPlanExecute plan_execute 主代理(规划侧)系统提示;非空且 agents/orchestrator-plan-execute.md 正文为空或未存在时生效。不与 Deep 的 orchestrator_instruction 混用。
|
// OrchestratorInstructionPlanExecute plan_execute 主代理(规划侧)系统提示;非空且 agents/orchestrator-plan-execute.md 正文为空或未存在时生效。不与 Deep 的 orchestrator_instruction 混用。
|
||||||
OrchestratorInstructionPlanExecute string `yaml:"orchestrator_instruction_plan_execute,omitempty" json:"orchestrator_instruction_plan_execute,omitempty"`
|
OrchestratorInstructionPlanExecute string `yaml:"orchestrator_instruction_plan_execute,omitempty" json:"orchestrator_instruction_plan_execute,omitempty"`
|
||||||
// OrchestratorInstructionSupervisor supervisor 主代理系统提示(transfer/exit 说明仍由运行追加);非空且 agents/orchestrator-supervisor.md 正文为空或未存在时生效。
|
// OrchestratorInstructionSupervisor supervisor 主代理系统提示(transfer/exit 说明仍由运行追加);非空且 agents/orchestrator-supervisor.md 正文为空或未存在时生效。
|
||||||
OrchestratorInstructionSupervisor string `yaml:"orchestrator_instruction_supervisor,omitempty" json:"orchestrator_instruction_supervisor,omitempty"`
|
OrchestratorInstructionSupervisor string `yaml:"orchestrator_instruction_supervisor,omitempty" json:"orchestrator_instruction_supervisor,omitempty"`
|
||||||
SubAgents []MultiAgentSubConfig `yaml:"sub_agents" json:"sub_agents"`
|
SubAgents []MultiAgentSubConfig `yaml:"sub_agents" json:"sub_agents"`
|
||||||
// SubAgentUserContextMaxRunes caps the user-context supplement appended to task descriptions for sub-agents.
|
// SubAgentUserContextMaxRunes caps the user-context supplement appended to task descriptions for sub-agents.
|
||||||
// 0 (default) uses the built-in default of 2000 runes; negative value disables injection entirely.
|
// 0 (default) uses the built-in default of 2000 runes; negative value disables injection entirely.
|
||||||
SubAgentUserContextMaxRunes int `yaml:"sub_agent_user_context_max_runes,omitempty" json:"sub_agent_user_context_max_runes,omitempty"`
|
SubAgentUserContextMaxRunes int `yaml:"sub_agent_user_context_max_runes,omitempty" json:"sub_agent_user_context_max_runes,omitempty"`
|
||||||
@@ -76,10 +77,10 @@ type MultiAgentEinoMiddlewareConfig struct {
|
|||||||
// PlantaskRelDir relative to skills_dir for per-conversation task boards (default .eino/plantask).
|
// PlantaskRelDir relative to skills_dir for per-conversation task boards (default .eino/plantask).
|
||||||
PlantaskRelDir string `yaml:"plantask_rel_dir,omitempty" json:"plantask_rel_dir,omitempty"`
|
PlantaskRelDir string `yaml:"plantask_rel_dir,omitempty" json:"plantask_rel_dir,omitempty"`
|
||||||
// Reduction truncates/offloads large tool outputs (requires eino local backend for Write).
|
// Reduction truncates/offloads large tool outputs (requires eino local backend for Write).
|
||||||
ReductionEnable bool `yaml:"reduction_enable,omitempty" json:"reduction_enable,omitempty"`
|
ReductionEnable bool `yaml:"reduction_enable,omitempty" json:"reduction_enable,omitempty"`
|
||||||
ReductionRootDir string `yaml:"reduction_root_dir,omitempty" json:"reduction_root_dir,omitempty"` // default: os temp + conversation id
|
ReductionRootDir string `yaml:"reduction_root_dir,omitempty" json:"reduction_root_dir,omitempty"` // default: os temp + conversation id
|
||||||
ReductionClearExclude []string `yaml:"reduction_clear_exclude,omitempty" json:"reduction_clear_exclude,omitempty"`
|
ReductionClearExclude []string `yaml:"reduction_clear_exclude,omitempty" json:"reduction_clear_exclude,omitempty"`
|
||||||
ReductionSubAgents bool `yaml:"reduction_sub_agents,omitempty" json:"reduction_sub_agents,omitempty"` // also attach to sub-agents
|
ReductionSubAgents bool `yaml:"reduction_sub_agents,omitempty" json:"reduction_sub_agents,omitempty"` // also attach to sub-agents
|
||||||
// CheckpointDir when non-empty enables adk.Runner CheckPointStore (file-backed) for interrupt/resume persistence.
|
// CheckpointDir when non-empty enables adk.Runner CheckPointStore (file-backed) for interrupt/resume persistence.
|
||||||
CheckpointDir string `yaml:"checkpoint_dir,omitempty" json:"checkpoint_dir,omitempty"`
|
CheckpointDir string `yaml:"checkpoint_dir,omitempty" json:"checkpoint_dir,omitempty"`
|
||||||
// DeepOutputKey passed to deep.Config OutputKey (session final text); empty = off.
|
// DeepOutputKey passed to deep.Config OutputKey (session final text); empty = off.
|
||||||
@@ -130,8 +131,8 @@ type MultiAgentSubConfig struct {
|
|||||||
|
|
||||||
// MultiAgentPublic 返回给前端的精简信息(不含子代理指令全文)。
|
// MultiAgentPublic 返回给前端的精简信息(不含子代理指令全文)。
|
||||||
type MultiAgentPublic struct {
|
type MultiAgentPublic struct {
|
||||||
Enabled bool `json:"enabled"`
|
Enabled bool `json:"enabled"`
|
||||||
RobotUseMultiAgent bool `json:"robot_use_multi_agent"`
|
RobotUseMultiAgent bool `json:"robot_use_multi_agent"`
|
||||||
BatchUseMultiAgent bool `json:"batch_use_multi_agent"`
|
BatchUseMultiAgent bool `json:"batch_use_multi_agent"`
|
||||||
SubAgentCount int `json:"sub_agent_count"`
|
SubAgentCount int `json:"sub_agent_count"`
|
||||||
Orchestration string `json:"orchestration,omitempty"`
|
Orchestration string `json:"orchestration,omitempty"`
|
||||||
@@ -155,8 +156,8 @@ func NormalizeMultiAgentOrchestration(s string) string {
|
|||||||
type MultiAgentAPIUpdate struct {
|
type MultiAgentAPIUpdate struct {
|
||||||
Enabled bool `json:"enabled"`
|
Enabled bool `json:"enabled"`
|
||||||
RobotUseMultiAgent bool `json:"robot_use_multi_agent"`
|
RobotUseMultiAgent bool `json:"robot_use_multi_agent"`
|
||||||
BatchUseMultiAgent bool `json:"batch_use_multi_agent"`
|
BatchUseMultiAgent bool `json:"batch_use_multi_agent"`
|
||||||
PlanExecuteLoopMaxIterations *int `json:"plan_execute_loop_max_iterations,omitempty"`
|
PlanExecuteLoopMaxIterations *int `json:"plan_execute_loop_max_iterations,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// RobotsConfig 机器人配置(企业微信、钉钉、飞书等)
|
// RobotsConfig 机器人配置(企业微信、钉钉、飞书等)
|
||||||
@@ -244,6 +245,13 @@ type AgentConfig struct {
|
|||||||
SystemPromptPath string `yaml:"system_prompt_path,omitempty" json:"system_prompt_path,omitempty"`
|
SystemPromptPath string `yaml:"system_prompt_path,omitempty" json:"system_prompt_path,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HitlConfig 人机协同全局选项;与会话侧栏/API 中的白名单合并为并集后参与判定。
|
||||||
|
// tool_whitelist 可在侧栏「应用」时合并写入 config.yaml 并立即生效;其他字段若仅改文件仍需重启。
|
||||||
|
type HitlConfig struct {
|
||||||
|
// ToolWhitelist 全局免审批工具名(与每条会话配置的 sensitiveTools 语义相同:白名单内工具不触发 HITL)。
|
||||||
|
ToolWhitelist []string `yaml:"tool_whitelist,omitempty" json:"tool_whitelist,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
type AuthConfig struct {
|
type AuthConfig struct {
|
||||||
Password string `yaml:"password" json:"password"`
|
Password string `yaml:"password" json:"password"`
|
||||||
SessionDurationHours int `yaml:"session_duration_hours" json:"session_duration_hours"`
|
SessionDurationHours int `yaml:"session_duration_hours" json:"session_duration_hours"`
|
||||||
@@ -950,10 +958,10 @@ type RolesConfig struct {
|
|||||||
|
|
||||||
// RoleConfig 单个角色配置
|
// RoleConfig 单个角色配置
|
||||||
type RoleConfig struct {
|
type RoleConfig struct {
|
||||||
Name string `yaml:"name" json:"name"` // 角色名称
|
Name string `yaml:"name" json:"name"` // 角色名称
|
||||||
Description string `yaml:"description" json:"description"` // 角色描述
|
Description string `yaml:"description" json:"description"` // 角色描述
|
||||||
UserPrompt string `yaml:"user_prompt" json:"user_prompt"` // 用户提示词(追加到用户消息前)
|
UserPrompt string `yaml:"user_prompt" json:"user_prompt"` // 用户提示词(追加到用户消息前)
|
||||||
Icon string `yaml:"icon,omitempty" json:"icon,omitempty"` // 角色图标(可选)
|
Icon string `yaml:"icon,omitempty" json:"icon,omitempty"` // 角色图标(可选)
|
||||||
Tools []string `yaml:"tools,omitempty" json:"tools,omitempty"` // 关联的工具列表(toolKey格式,如 "toolName" 或 "mcpName::toolName")
|
Tools []string `yaml:"tools,omitempty" json:"tools,omitempty"` // 关联的工具列表(toolKey格式,如 "toolName" 或 "mcpName::toolName")
|
||||||
MCPs []string `yaml:"mcps,omitempty" json:"mcps,omitempty"` // 向后兼容:关联的MCP服务器列表(已废弃,使用tools替代)
|
MCPs []string `yaml:"mcps,omitempty" json:"mcps,omitempty"` // 向后兼容:关联的MCP服务器列表(已废弃,使用tools替代)
|
||||||
Enabled bool `yaml:"enabled" json:"enabled"` // 是否启用
|
Enabled bool `yaml:"enabled" json:"enabled"` // 是否启用
|
||||||
|
|||||||
@@ -230,6 +230,17 @@ attemptLoop:
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if ev.Err != nil {
|
if ev.Err != nil {
|
||||||
|
if errors.Is(ev.Err, context.DeadlineExceeded) {
|
||||||
|
flushAllPendingAsFailed(ev.Err)
|
||||||
|
if progress != nil {
|
||||||
|
progress("error", ev.Err.Error(), map[string]interface{}{
|
||||||
|
"conversationId": conversationID,
|
||||||
|
"source": "eino",
|
||||||
|
"errorKind": "timeout",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return nil, ev.Err
|
||||||
|
}
|
||||||
// context.Canceled 是唯一应当直接终止编排的错误(用户关闭页面、主动停止等)。
|
// context.Canceled 是唯一应当直接终止编排的错误(用户关闭页面、主动停止等)。
|
||||||
if errors.Is(ev.Err, context.Canceled) {
|
if errors.Is(ev.Err, context.Canceled) {
|
||||||
flushAllPendingAsFailed(ev.Err)
|
flushAllPendingAsFailed(ev.Err)
|
||||||
|
|||||||
@@ -159,6 +159,7 @@ func RunEinoSingleChatModelAgent(
|
|||||||
Tools: mainToolsForCfg,
|
Tools: mainToolsForCfg,
|
||||||
UnknownToolsHandler: einomcp.UnknownToolReminderHandler(),
|
UnknownToolsHandler: einomcp.UnknownToolReminderHandler(),
|
||||||
ToolCallMiddlewares: []compose.ToolMiddleware{
|
ToolCallMiddlewares: []compose.ToolMiddleware{
|
||||||
|
{Invokable: hitlToolCallMiddleware()},
|
||||||
{Invokable: softRecoveryToolCallMiddleware()},
|
{Invokable: softRecoveryToolCallMiddleware()},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -0,0 +1,81 @@
|
|||||||
|
package multiagent
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/cloudwego/eino/adk"
|
||||||
|
"github.com/cloudwego/eino/compose"
|
||||||
|
)
|
||||||
|
|
||||||
|
type hitlInterceptorKey struct{}
|
||||||
|
|
||||||
|
type HITLToolInterceptor func(ctx context.Context, toolName, arguments string) (string, error)
|
||||||
|
|
||||||
|
type humanRejectError struct {
|
||||||
|
reason string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *humanRejectError) Error() string {
|
||||||
|
if strings.TrimSpace(e.reason) == "" {
|
||||||
|
return "rejected by user"
|
||||||
|
}
|
||||||
|
return "rejected by user: " + strings.TrimSpace(e.reason)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewHumanRejectError(reason string) error {
|
||||||
|
return &humanRejectError{reason: strings.TrimSpace(reason)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func IsHumanRejectError(err error) bool {
|
||||||
|
var target *humanRejectError
|
||||||
|
return errors.As(err, &target)
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithHITLToolInterceptor(ctx context.Context, fn HITLToolInterceptor) context.Context {
|
||||||
|
if fn == nil {
|
||||||
|
return ctx
|
||||||
|
}
|
||||||
|
return context.WithValue(ctx, hitlInterceptorKey{}, fn)
|
||||||
|
}
|
||||||
|
|
||||||
|
func hitlToolCallMiddleware() compose.InvokableToolMiddleware {
|
||||||
|
return func(next compose.InvokableToolEndpoint) compose.InvokableToolEndpoint {
|
||||||
|
return func(ctx context.Context, input *compose.ToolInput) (*compose.ToolOutput, error) {
|
||||||
|
if input != nil {
|
||||||
|
if fn, ok := ctx.Value(hitlInterceptorKey{}).(HITLToolInterceptor); ok && fn != nil {
|
||||||
|
edited, err := fn(ctx, input.Name, input.Arguments)
|
||||||
|
if err != nil {
|
||||||
|
if IsHumanRejectError(err) {
|
||||||
|
// Human rejection should be a soft tool result so the model can continue iterating.
|
||||||
|
msg := fmt.Sprintf("[HITL Reject] Tool '%s' was rejected by human reviewer. Reason: %s\nPlease adjust parameters/plan and continue without this call.",
|
||||||
|
input.Name, strings.TrimSpace(err.Error()))
|
||||||
|
// transfer_to_agent 在 Eino 中标记为 returnDirectly:工具成功后 ReAct 子图会直接 END,
|
||||||
|
// 并依赖真实工具内的 SendToolGenAction 触发移交。HITL 拒绝时不会执行真实工具,
|
||||||
|
// 若仍走 returnDirectly 分支,监督者会在无 Transfer 动作的情况下结束,模型不再迭代。
|
||||||
|
if strings.EqualFold(strings.TrimSpace(input.Name), adk.TransferToAgentToolName) {
|
||||||
|
_ = compose.ProcessState[*adk.State](ctx, func(_ context.Context, st *adk.State) error {
|
||||||
|
if st == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
st.ReturnDirectlyToolCallID = ""
|
||||||
|
st.HasReturnDirectly = false
|
||||||
|
st.ReturnDirectlyEvent = nil
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return &compose.ToolOutput{Result: msg}, nil
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if edited != "" {
|
||||||
|
input.Arguments = edited
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return next(ctx, input)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -268,6 +268,7 @@ func RunDeepAgent(
|
|||||||
Tools: subToolsForCfg,
|
Tools: subToolsForCfg,
|
||||||
UnknownToolsHandler: einomcp.UnknownToolReminderHandler(),
|
UnknownToolsHandler: einomcp.UnknownToolReminderHandler(),
|
||||||
ToolCallMiddlewares: []compose.ToolMiddleware{
|
ToolCallMiddlewares: []compose.ToolMiddleware{
|
||||||
|
{Invokable: hitlToolCallMiddleware()},
|
||||||
{Invokable: softRecoveryToolCallMiddleware()},
|
{Invokable: softRecoveryToolCallMiddleware()},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -366,6 +367,7 @@ func RunDeepAgent(
|
|||||||
Tools: mainToolsForCfg,
|
Tools: mainToolsForCfg,
|
||||||
UnknownToolsHandler: einomcp.UnknownToolReminderHandler(),
|
UnknownToolsHandler: einomcp.UnknownToolReminderHandler(),
|
||||||
ToolCallMiddlewares: []compose.ToolMiddleware{
|
ToolCallMiddlewares: []compose.ToolMiddleware{
|
||||||
|
{Invokable: hitlToolCallMiddleware()},
|
||||||
{Invokable: softRecoveryToolCallMiddleware()},
|
{Invokable: softRecoveryToolCallMiddleware()},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user