mirror of
https://github.com/Ed1s0nZ/CyberStrikeAI.git
synced 2026-06-05 22:06:41 +02:00
Add files via upload
This commit is contained in:
@@ -494,8 +494,7 @@ func (h *AgentHandler) AgentLoop(c *gin.Context) {
|
||||
|
||||
// 应用角色用户提示词和工具配置
|
||||
finalMessage := req.Message
|
||||
var roleTools []string // 角色配置的工具列表
|
||||
var roleSkills []string // 角色配置的skills列表(用于提示AI,但不硬编码内容)
|
||||
var roleTools []string // 角色配置的工具列表
|
||||
|
||||
// WebShell AI 助手模式:绑定当前连接,仅开放 webshell_* 工具并注入 connection_id
|
||||
if req.WebShellConnectionID != "" {
|
||||
@@ -531,7 +530,6 @@ func (h *AgentHandler) AgentLoop(c *gin.Context) {
|
||||
builtin.ToolListKnowledgeRiskTypes,
|
||||
builtin.ToolSearchKnowledgeBase,
|
||||
}
|
||||
roleSkills = nil
|
||||
} else if req.Role != "" && req.Role != "默认" {
|
||||
if h.config.Roles != nil {
|
||||
if role, exists := h.config.Roles[req.Role]; exists && role.Enabled {
|
||||
@@ -545,11 +543,6 @@ func (h *AgentHandler) AgentLoop(c *gin.Context) {
|
||||
roleTools = role.Tools
|
||||
h.logger.Info("使用角色配置的工具列表", zap.String("role", req.Role), zap.Int("toolCount", len(roleTools)))
|
||||
}
|
||||
// 获取角色配置的skills列表(用于在系统提示词中提示AI,但不硬编码内容)
|
||||
if len(role.Skills) > 0 {
|
||||
roleSkills = role.Skills
|
||||
h.logger.Info("角色配置了skills,将在系统提示词中提示AI", zap.String("role", req.Role), zap.Int("skillCount", len(roleSkills)), zap.Strings("skills", roleSkills))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -574,8 +567,7 @@ func (h *AgentHandler) AgentLoop(c *gin.Context) {
|
||||
}
|
||||
|
||||
// 执行Agent Loop,传入历史消息和对话ID(使用包含角色提示词的finalMessage和角色工具列表)
|
||||
// 注意:skills不会硬编码注入,但会在系统提示词中提示AI这个角色推荐使用哪些skills
|
||||
result, err := h.agent.AgentLoopWithProgress(c.Request.Context(), finalMessage, agentHistoryMessages, conversationID, nil, roleTools, roleSkills)
|
||||
result, err := h.agent.AgentLoopWithProgress(c.Request.Context(), finalMessage, agentHistoryMessages, conversationID, nil, roleTools)
|
||||
if err != nil {
|
||||
h.logger.Error("Agent Loop执行失败", zap.Error(err))
|
||||
|
||||
@@ -646,14 +638,13 @@ func (h *AgentHandler) ProcessMessageForRobot(ctx context.Context, conversationI
|
||||
}
|
||||
|
||||
finalMessage := message
|
||||
var roleTools, roleSkills []string
|
||||
var roleTools []string
|
||||
if role != "" && role != "默认" && h.config.Roles != nil {
|
||||
if r, exists := h.config.Roles[role]; exists && r.Enabled {
|
||||
if r.UserPrompt != "" {
|
||||
finalMessage = r.UserPrompt + "\n\n" + message
|
||||
}
|
||||
roleTools = r.Tools
|
||||
roleSkills = r.Skills
|
||||
}
|
||||
}
|
||||
|
||||
@@ -720,7 +711,7 @@ func (h *AgentHandler) ProcessMessageForRobot(ctx context.Context, conversationI
|
||||
return resultMA.Response, conversationID, nil
|
||||
}
|
||||
|
||||
result, err := h.agent.AgentLoopWithProgress(ctx, finalMessage, agentHistoryMessages, conversationID, progressCallback, roleTools, roleSkills)
|
||||
result, err := h.agent.AgentLoopWithProgress(ctx, finalMessage, agentHistoryMessages, conversationID, progressCallback, roleTools)
|
||||
if err != nil {
|
||||
errMsg := "执行失败: " + err.Error()
|
||||
if assistantMessageID != "" {
|
||||
@@ -1263,7 +1254,6 @@ func (h *AgentHandler) AgentLoopStream(c *gin.Context) {
|
||||
// 应用角色用户提示词和工具配置
|
||||
finalMessage := req.Message
|
||||
var roleTools []string // 角色配置的工具列表
|
||||
var roleSkills []string
|
||||
if req.WebShellConnectionID != "" {
|
||||
conn, errConn := h.db.GetWebshellConnection(strings.TrimSpace(req.WebShellConnectionID))
|
||||
if errConn != nil || conn == nil {
|
||||
@@ -1314,11 +1304,6 @@ func (h *AgentHandler) AgentLoopStream(c *gin.Context) {
|
||||
// 因为mcps是MCP服务器名称,不是工具列表
|
||||
h.logger.Info("角色配置使用旧的mcps字段,将使用所有工具", zap.String("role", req.Role))
|
||||
}
|
||||
// 注意:角色 skills 仅在系统提示词中提示;运行时加载请使用 Eino 多代理内置 `skill` 工具
|
||||
if len(role.Skills) > 0 {
|
||||
roleSkills = role.Skills
|
||||
h.logger.Info("角色配置了skills,AI可通过工具按需调用", zap.String("role", req.Role), zap.Int("skillCount", len(role.Skills)), zap.Strings("skills", role.Skills))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1423,12 +1408,11 @@ func (h *AgentHandler) AgentLoopStream(c *gin.Context) {
|
||||
|
||||
// 执行Agent Loop,传入独立的上下文,确保任务不会因客户端断开而中断(使用包含角色提示词的finalMessage和角色工具列表)
|
||||
sendEvent("progress", "正在分析您的请求...", nil)
|
||||
// 注意:roleSkills 已在上方根据 req.Role 或 WebShell 模式设置
|
||||
stopKeepalive := make(chan struct{})
|
||||
go sseKeepalive(c, stopKeepalive, &sseWriteMu)
|
||||
defer close(stopKeepalive)
|
||||
|
||||
result, err := h.agent.AgentLoopWithProgress(taskCtx, finalMessage, agentHistoryMessages, conversationID, progressCallback, roleTools, roleSkills)
|
||||
result, err := h.agent.AgentLoopWithProgress(taskCtx, finalMessage, agentHistoryMessages, conversationID, progressCallback, roleTools)
|
||||
if err != nil {
|
||||
h.logger.Error("Agent Loop执行失败", zap.Error(err))
|
||||
cause := context.Cause(baseCtx)
|
||||
@@ -2242,8 +2226,7 @@ func (h *AgentHandler) executeBatchQueue(queueID string) {
|
||||
|
||||
// 应用角色用户提示词和工具配置
|
||||
finalMessage := task.Message
|
||||
var roleTools []string // 角色配置的工具列表
|
||||
var roleSkills []string // 角色配置的skills列表(用于提示AI,但不硬编码内容)
|
||||
var roleTools []string // 角色配置的工具列表
|
||||
if queue.Role != "" && queue.Role != "默认" {
|
||||
if h.config.Roles != nil {
|
||||
if role, exists := h.config.Roles[queue.Role]; exists && role.Enabled {
|
||||
@@ -2257,11 +2240,6 @@ func (h *AgentHandler) executeBatchQueue(queueID string) {
|
||||
roleTools = role.Tools
|
||||
h.logger.Info("使用角色配置的工具列表", zap.String("queueId", queueID), zap.String("taskId", task.ID), zap.String("role", queue.Role), zap.Int("toolCount", len(roleTools)))
|
||||
}
|
||||
// 获取角色配置的skills列表(用于在系统提示词中提示AI,但不硬编码内容)
|
||||
if len(role.Skills) > 0 {
|
||||
roleSkills = role.Skills
|
||||
h.logger.Info("角色配置了skills,将在系统提示词中提示AI", zap.String("queueId", queueID), zap.String("taskId", task.ID), zap.String("role", queue.Role), zap.Int("skillCount", len(roleSkills)), zap.Strings("skills", roleSkills))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2295,7 +2273,6 @@ func (h *AgentHandler) executeBatchQueue(queueID string) {
|
||||
// 存储取消函数,以便在取消队列时能够取消当前任务
|
||||
h.batchTaskManager.SetTaskCancel(queueID, cancel)
|
||||
// 使用队列配置的角色工具列表(如果为空,表示使用所有工具)
|
||||
// 注意:skills不会硬编码注入,但会在系统提示词中提示AI这个角色推荐使用哪些skills
|
||||
useBatchMulti := false
|
||||
useEinoSingle := false
|
||||
batchOrch := "deep"
|
||||
@@ -2326,10 +2303,10 @@ func (h *AgentHandler) executeBatchQueue(queueID string) {
|
||||
if h.config == nil {
|
||||
runErr = fmt.Errorf("服务器配置未加载")
|
||||
} else {
|
||||
resultMA, runErr = multiagent.RunEinoSingleChatModelAgent(ctx, h.config, &h.config.MultiAgent, h.agent, h.logger, conversationID, finalMessage, []agent.ChatMessage{}, roleTools, roleSkills, progressCallback)
|
||||
resultMA, runErr = multiagent.RunEinoSingleChatModelAgent(ctx, h.config, &h.config.MultiAgent, h.agent, h.logger, conversationID, finalMessage, []agent.ChatMessage{}, roleTools, progressCallback)
|
||||
}
|
||||
default:
|
||||
result, runErr = h.agent.AgentLoopWithProgress(ctx, finalMessage, []agent.ChatMessage{}, conversationID, progressCallback, roleTools, roleSkills)
|
||||
result, runErr = h.agent.AgentLoopWithProgress(ctx, finalMessage, []agent.ChatMessage{}, conversationID, progressCallback, roleTools)
|
||||
}
|
||||
// 任务执行完成,清理取消函数
|
||||
h.batchTaskManager.SetTaskCancel(queueID, nil)
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
@@ -305,6 +306,8 @@ func (h *ConfigHandler) GetTools(c *gin.Context) {
|
||||
h.mu.RLock()
|
||||
defer h.mu.RUnlock()
|
||||
|
||||
c.Header("Cache-Control", "no-store, no-cache, must-revalidate")
|
||||
|
||||
// 解析分页参数
|
||||
page := 1
|
||||
pageSize := 20
|
||||
@@ -326,15 +329,26 @@ func (h *ConfigHandler) GetTools(c *gin.Context) {
|
||||
searchTermLower = strings.ToLower(searchTerm)
|
||||
}
|
||||
|
||||
// 解析状态筛选参数: "true" = 仅已启用, "false" = 仅已停用, "" = 全部
|
||||
enabledFilter := c.Query("enabled")
|
||||
// 解析状态筛选: tool_filter=on|off(角色弹窗等优先,避免与网关/代理对 enabled 的特殊处理冲突)
|
||||
// 兼容旧参数 enabled=true|false
|
||||
var filterEnabled *bool
|
||||
if enabledFilter == "true" {
|
||||
toolFilter := strings.TrimSpace(strings.ToLower(c.Query("tool_filter")))
|
||||
switch toolFilter {
|
||||
case "on", "1", "true", "enabled":
|
||||
v := true
|
||||
filterEnabled = &v
|
||||
} else if enabledFilter == "false" {
|
||||
case "off", "0", "false", "disabled":
|
||||
v := false
|
||||
filterEnabled = &v
|
||||
default:
|
||||
enabledFilter := strings.TrimSpace(c.Query("enabled"))
|
||||
if enabledFilter == "true" {
|
||||
v := true
|
||||
filterEnabled = &v
|
||||
} else if enabledFilter == "false" {
|
||||
v := false
|
||||
filterEnabled = &v
|
||||
}
|
||||
}
|
||||
|
||||
// 解析角色参数,用于过滤工具并标注启用状态
|
||||
@@ -521,6 +535,17 @@ func (h *ConfigHandler) GetTools(c *gin.Context) {
|
||||
// 注意:这里我们不直接过滤掉工具,而是保留所有工具,但通过 role_enabled 字段标注状态
|
||||
// 这样前端可以显示所有工具,并标注哪些工具在当前角色中可用
|
||||
|
||||
// 统一按名称排序后再分页,避免配置文件中顺序导致「全部」与「仅已启用」前几页看起来完全一致
|
||||
sort.SliceStable(allTools, func(i, j int) bool {
|
||||
key := func(t ToolConfigInfo) string {
|
||||
if t.IsExternal && t.ExternalMCP != "" {
|
||||
return strings.ToLower(t.ExternalMCP + "::" + t.Name)
|
||||
}
|
||||
return strings.ToLower(t.Name)
|
||||
}
|
||||
return key(allTools[i]) < key(allTools[j])
|
||||
})
|
||||
|
||||
total := len(allTools)
|
||||
// 统计已启用的工具数(在角色中的启用工具数)
|
||||
totalEnabled := 0
|
||||
|
||||
@@ -151,7 +151,6 @@ func (h *AgentHandler) EinoSingleAgentLoopStream(c *gin.Context) {
|
||||
prep.FinalMessage,
|
||||
prep.History,
|
||||
prep.RoleTools,
|
||||
prep.RoleSkills,
|
||||
progressCallback,
|
||||
)
|
||||
|
||||
@@ -255,7 +254,6 @@ func (h *AgentHandler) EinoSingleAgentLoop(c *gin.Context) {
|
||||
prep.FinalMessage,
|
||||
prep.History,
|
||||
prep.RoleTools,
|
||||
prep.RoleSkills,
|
||||
progressCallback,
|
||||
)
|
||||
if runErr != nil {
|
||||
|
||||
@@ -18,7 +18,6 @@ type multiAgentPrepared struct {
|
||||
History []agent.ChatMessage
|
||||
FinalMessage string
|
||||
RoleTools []string
|
||||
RoleSkills []string
|
||||
AssistantMessageID string
|
||||
UserMessageID string
|
||||
}
|
||||
@@ -68,7 +67,6 @@ func (h *AgentHandler) prepareMultiAgentSession(req *ChatRequest) (*multiAgentPr
|
||||
|
||||
finalMessage := req.Message
|
||||
var roleTools []string
|
||||
var roleSkills []string
|
||||
if req.WebShellConnectionID != "" {
|
||||
conn, errConn := h.db.GetWebshellConnection(strings.TrimSpace(req.WebShellConnectionID))
|
||||
if errConn != nil || conn == nil {
|
||||
@@ -107,7 +105,6 @@ func (h *AgentHandler) prepareMultiAgentSession(req *ChatRequest) (*multiAgentPr
|
||||
finalMessage = role.UserPrompt + "\n\n" + req.Message
|
||||
}
|
||||
roleTools = role.Tools
|
||||
roleSkills = role.Skills
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,7 +143,6 @@ func (h *AgentHandler) prepareMultiAgentSession(req *ChatRequest) (*multiAgentPr
|
||||
History: agentHistoryMessages,
|
||||
FinalMessage: finalMessage,
|
||||
RoleTools: roleTools,
|
||||
RoleSkills: roleSkills,
|
||||
AssistantMessageID: assistantMessageID,
|
||||
UserMessageID: userMessageID,
|
||||
}, nil
|
||||
|
||||
@@ -648,13 +648,6 @@ func (h *OpenAPIHandler) GetOpenAPISpec(c *gin.Context) {
|
||||
"type": "string",
|
||||
},
|
||||
},
|
||||
"skills": map[string]interface{}{
|
||||
"type": "array",
|
||||
"description": "Skills列表",
|
||||
"items": map[string]interface{}{
|
||||
"type": "string",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"Skill": map[string]interface{}{
|
||||
@@ -2879,38 +2872,6 @@ func (h *OpenAPIHandler) GetOpenAPISpec(c *gin.Context) {
|
||||
},
|
||||
},
|
||||
},
|
||||
"/api/roles/skills/list": map[string]interface{}{
|
||||
"get": map[string]interface{}{
|
||||
"tags": []string{"角色管理"},
|
||||
"summary": "获取可用Skills列表",
|
||||
"description": "获取所有可用的Skills列表,用于角色配置",
|
||||
"operationId": "getSkills",
|
||||
"responses": map[string]interface{}{
|
||||
"200": map[string]interface{}{
|
||||
"description": "获取成功",
|
||||
"content": map[string]interface{}{
|
||||
"application/json": map[string]interface{}{
|
||||
"schema": map[string]interface{}{
|
||||
"type": "object",
|
||||
"properties": map[string]interface{}{
|
||||
"skills": map[string]interface{}{
|
||||
"type": "array",
|
||||
"description": "Skills列表",
|
||||
"items": map[string]interface{}{
|
||||
"type": "string",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"401": map[string]interface{}{
|
||||
"description": "未授权",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"/api/skills": map[string]interface{}{
|
||||
"get": map[string]interface{}{
|
||||
"tags": []string{"Skills管理"},
|
||||
|
||||
@@ -18,15 +18,9 @@ import (
|
||||
|
||||
// RoleHandler 角色处理器
|
||||
type RoleHandler struct {
|
||||
config *config.Config
|
||||
configPath string
|
||||
logger *zap.Logger
|
||||
skillsManager SkillsManager // Skills管理器接口(可选)
|
||||
}
|
||||
|
||||
// SkillsManager Skills管理器接口
|
||||
type SkillsManager interface {
|
||||
ListSkills() ([]string, error)
|
||||
config *config.Config
|
||||
configPath string
|
||||
logger *zap.Logger
|
||||
}
|
||||
|
||||
// NewRoleHandler 创建新的角色处理器
|
||||
@@ -38,34 +32,6 @@ func NewRoleHandler(cfg *config.Config, configPath string, logger *zap.Logger) *
|
||||
}
|
||||
}
|
||||
|
||||
// SetSkillsManager 设置Skills管理器
|
||||
func (h *RoleHandler) SetSkillsManager(manager SkillsManager) {
|
||||
h.skillsManager = manager
|
||||
}
|
||||
|
||||
// GetSkills 获取所有可用的skills列表
|
||||
func (h *RoleHandler) GetSkills(c *gin.Context) {
|
||||
if h.skillsManager == nil {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"skills": []string{},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
skills, err := h.skillsManager.ListSkills()
|
||||
if err != nil {
|
||||
h.logger.Warn("获取skills列表失败", zap.Error(err))
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"skills": []string{},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"skills": skills,
|
||||
})
|
||||
}
|
||||
|
||||
// GetRoles 获取所有角色
|
||||
func (h *RoleHandler) GetRoles(c *gin.Context) {
|
||||
if h.config.Roles == nil {
|
||||
|
||||
@@ -308,31 +308,10 @@ func (h *SkillsHandler) GetSkillBoundRoles(c *gin.Context) {
|
||||
})
|
||||
}
|
||||
|
||||
// getRolesBoundToSkill 获取绑定指定skill的角色列表(不修改配置)
|
||||
// getRolesBoundToSkill 预留:角色不再配置 skill 绑定,始终返回空列表。
|
||||
func (h *SkillsHandler) getRolesBoundToSkill(skillName string) []string {
|
||||
if h.config.Roles == nil {
|
||||
return []string{}
|
||||
}
|
||||
|
||||
boundRoles := make([]string, 0)
|
||||
for roleName, role := range h.config.Roles {
|
||||
// 确保角色名称正确设置
|
||||
if role.Name == "" {
|
||||
role.Name = roleName
|
||||
}
|
||||
|
||||
// 检查角色的Skills列表中是否包含该skill
|
||||
if len(role.Skills) > 0 {
|
||||
for _, skill := range role.Skills {
|
||||
if skill == skillName {
|
||||
boundRoles = append(boundRoles, roleName)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return boundRoles
|
||||
_ = skillName
|
||||
return nil
|
||||
}
|
||||
|
||||
// CreateSkill 创建新 skill(标准 Agent Skills:生成 SKILL.md + YAML front matter)
|
||||
@@ -600,55 +579,10 @@ func (h *SkillsHandler) ClearSkillStatsByName(c *gin.Context) {
|
||||
})
|
||||
}
|
||||
|
||||
// removeSkillFromRoles 从所有角色中移除指定的skill绑定
|
||||
// 返回受影响角色名称列表
|
||||
// removeSkillFromRoles 预留:角色不再存储 skill 绑定,无操作。
|
||||
func (h *SkillsHandler) removeSkillFromRoles(skillName string) []string {
|
||||
if h.config.Roles == nil {
|
||||
return []string{}
|
||||
}
|
||||
|
||||
affectedRoles := make([]string, 0)
|
||||
rolesToUpdate := make(map[string]config.RoleConfig)
|
||||
|
||||
// 遍历所有角色,查找并移除skill绑定
|
||||
for roleName, role := range h.config.Roles {
|
||||
// 确保角色名称正确设置
|
||||
if role.Name == "" {
|
||||
role.Name = roleName
|
||||
}
|
||||
|
||||
// 检查角色的Skills列表中是否包含要删除的skill
|
||||
if len(role.Skills) > 0 {
|
||||
updated := false
|
||||
newSkills := make([]string, 0, len(role.Skills))
|
||||
for _, skill := range role.Skills {
|
||||
if skill != skillName {
|
||||
newSkills = append(newSkills, skill)
|
||||
} else {
|
||||
updated = true
|
||||
}
|
||||
}
|
||||
if updated {
|
||||
role.Skills = newSkills
|
||||
rolesToUpdate[roleName] = role
|
||||
affectedRoles = append(affectedRoles, roleName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 如果有角色需要更新,保存到文件
|
||||
if len(rolesToUpdate) > 0 {
|
||||
// 更新内存中的配置
|
||||
for roleName, role := range rolesToUpdate {
|
||||
h.config.Roles[roleName] = role
|
||||
}
|
||||
// 保存更新后的角色配置到文件
|
||||
if err := h.saveRolesConfig(); err != nil {
|
||||
h.logger.Error("保存角色配置失败", zap.Error(err))
|
||||
}
|
||||
}
|
||||
|
||||
return affectedRoles
|
||||
_ = skillName
|
||||
return nil
|
||||
}
|
||||
|
||||
// saveRolesConfig 保存角色配置到文件(从SkillsHandler调用)
|
||||
|
||||
Reference in New Issue
Block a user