diff --git a/internal/ai/runtime/internal/engine/service.go b/internal/ai/runtime/internal/engine/service.go index c7195cf..55d6df6 100644 --- a/internal/ai/runtime/internal/engine/service.go +++ b/internal/ai/runtime/internal/engine/service.go @@ -113,7 +113,7 @@ func (s *Service) Run(ctx context.Context, req Request) (*Summary, error) { if req.SelectedSkill != nil { summary.SelectedSkillCode = strings.TrimSpace(req.SelectedSkill.Code) summary.SelectedSkillName = strings.TrimSpace(req.SelectedSkill.Name) - summary.SkillAllowedToolCodes = parseJSONArrayList(req.SelectedSkill.AllowedToolCodes) + summary.SkillAllowedToolCodes = parseJSONArrayList(req.SelectedSkill.ToolWhitelist) collector.Data.Skill.Code = summary.SelectedSkillCode collector.Data.Skill.Name = summary.SelectedSkillName collector.Data.Skill.AllowedToolCodes = append([]string(nil), summary.SkillAllowedToolCodes...) @@ -315,7 +315,7 @@ func filterToolDefinitionsBySkill(definitions []adapter.MCPToolDefinition, skill if len(definitions) == 0 || skill == nil { return definitions } - allowed := parseJSONArraySet(skill.AllowedToolCodes) + allowed := parseJSONArraySet(skill.ToolWhitelist) if len(allowed) == 0 { return definitions } diff --git a/internal/ai/runtime/service.go b/internal/ai/runtime/service.go index 4ec85cf..94c5a93 100644 --- a/internal/ai/runtime/service.go +++ b/internal/ai/runtime/service.go @@ -205,7 +205,7 @@ func parseSkillAllowedToolCodes(skill *models.SkillDefinition) []string { if skill == nil { return nil } - raw := strings.TrimSpace(skill.AllowedToolCodes) + raw := strings.TrimSpace(skill.ToolWhitelist) if raw == "" { return nil } diff --git a/internal/builders/skill_builder.go b/internal/builders/skill_builder.go index 76ca544..9b0cb4a 100644 --- a/internal/builders/skill_builder.go +++ b/internal/builders/skill_builder.go @@ -13,26 +13,26 @@ func BuildSkillDefinitionResponse(item *models.SkillDefinition) response.SkillDe if raw := item.Examples; raw != "" { _ = json.Unmarshal([]byte(raw), &examples) } - allowedToolCodes := make([]string, 0) - if raw := item.AllowedToolCodes; raw != "" { - _ = json.Unmarshal([]byte(raw), &allowedToolCodes) + toolWhitelist := make([]string, 0) + if raw := item.ToolWhitelist; raw != "" { + _ = json.Unmarshal([]byte(raw), &toolWhitelist) } return response.SkillDefinitionResponse{ - ID: item.ID, - Code: item.Code, - Name: item.Name, - Description: item.Description, - Instruction: item.Instruction, - Examples: examples, - AllowedToolCodes: allowedToolCodes, - Priority: item.Priority, - Status: int(item.Status), - StatusName: getSkillStatusName(item.Status), - Remark: item.Remark, - CreatedAt: item.CreatedAt, - UpdatedAt: item.UpdatedAt, - CreateUserName: item.CreateUserName, - UpdateUserName: item.UpdateUserName, + ID: item.ID, + Code: item.Code, + Name: item.Name, + Description: item.Description, + Instruction: item.Instruction, + Examples: examples, + ToolWhitelist: toolWhitelist, + Priority: item.Priority, + Status: int(item.Status), + StatusName: getSkillStatusName(item.Status), + Remark: item.Remark, + CreatedAt: item.CreatedAt, + UpdatedAt: item.UpdatedAt, + CreateUserName: item.CreateUserName, + UpdateUserName: item.UpdateUserName, } } diff --git a/internal/models/models.go b/internal/models/models.go index b2268c6..a99f1f4 100644 --- a/internal/models/models.go +++ b/internal/models/models.go @@ -904,16 +904,16 @@ type KnowledgeFeedback struct { // SkillDefinition 表示可由后台配置并参与运行时路由的 Skill 定义。 type SkillDefinition struct { - ID int64 `gorm:"primaryKey;autoIncrement"` // ID 为 Skill 主键。 - Code string `gorm:"type:varchar(100);not null;default:'';uniqueIndex"` // Code 为 Skill 的稳定唯一编码,供程序内部引用和路由判断使用,例如 refund_skill。 - Name string `gorm:"type:varchar(100);not null;default:'';index"` // Name 为 Skill 的展示名称,用于后台列表、配置页和人工选择场景。 - Description string `gorm:"type:varchar(255);not null;default:''"` // Description 为 Skill 的简要说明,用于描述该 Skill 的适用场景和职责边界。 - Instruction string `gorm:"type:longtext"` // Instruction 为 Skill 的主体说明文档存储字段,使用 Markdown 编写,供 Agent 理解任务目标、步骤和工具使用要求。 - Examples string `gorm:"type:text"` // Examples 为示例问法 JSON 数组字符串。 - AllowedToolCodes string `gorm:"type:text"` // AllowedToolCodes 为允许使用的工具编码 JSON 数组字符串。 - Priority int `gorm:"type:int;not null;default:0;index"` // Priority 为 Skill 命中冲突时的优先级,数值越大优先级越高。 - Status enums.Status `gorm:"type:int;not null;default:0;index"` // Status 为 Skill 当前状态,使用全局通用状态:0启用 1禁用 2删除。 - Remark string `gorm:"type:text"` // Remark 为后台备注,用于记录配置说明、维护信息或内部协作信息。 + ID int64 `gorm:"primaryKey;autoIncrement"` // ID 为 Skill 主键。 + Code string `gorm:"type:varchar(100);not null;default:'';uniqueIndex"` // Code 为 Skill 的稳定唯一编码,供程序内部引用和路由判断使用,例如 refund_skill。 + Name string `gorm:"type:varchar(100);not null;default:'';index"` // Name 为 Skill 的展示名称,用于后台列表、配置页和人工选择场景。 + Description string `gorm:"type:varchar(255);not null;default:''"` // Description 为 Skill 的简要说明,用于描述该 Skill 的适用场景和职责边界。 + Instruction string `gorm:"type:longtext"` // Instruction 为 Skill 的主体说明文档存储字段,使用 Markdown 编写,供 Agent 理解任务目标、步骤和工具使用要求。 + Examples string `gorm:"type:text"` // Examples 为示例问法 JSON 数组字符串。 + ToolWhitelist string `gorm:"type:text"` // ToolWhitelist 为允许使用的工具编码 JSON 数组字符串。 + Priority int `gorm:"type:int;not null;default:0;index"` // Priority 为 Skill 命中冲突时的优先级,数值越大优先级越高。 + Status enums.Status `gorm:"type:int;not null;default:0;index"` // Status 为 Skill 当前状态,使用全局通用状态:0启用 1禁用 2删除。 + Remark string `gorm:"type:text"` // Remark 为后台备注,用于记录配置说明、维护信息或内部协作信息。 AuditFields } diff --git a/internal/pkg/dto/request/skill_request.go b/internal/pkg/dto/request/skill_request.go index 1bcad94..4e3ed98 100644 --- a/internal/pkg/dto/request/skill_request.go +++ b/internal/pkg/dto/request/skill_request.go @@ -7,14 +7,14 @@ type SkillDefinitionListRequest struct { } type CreateSkillDefinitionRequest struct { - Code string `json:"code"` - Name string `json:"name"` - Description string `json:"description"` - Instruction string `json:"instruction"` - Examples []string `json:"examples"` - AllowedToolCodes []string `json:"allowedToolCodes"` - Priority int `json:"priority"` - Remark string `json:"remark"` + Code string `json:"code"` + Name string `json:"name"` + Description string `json:"description"` + Instruction string `json:"instruction"` + Examples []string `json:"examples"` + ToolWhitelist []string `json:"toolWhitelist"` + Priority int `json:"priority"` + Remark string `json:"remark"` } type UpdateSkillDefinitionRequest struct { diff --git a/internal/pkg/dto/response/skill_response.go b/internal/pkg/dto/response/skill_response.go index 3dec52f..f45cc0a 100644 --- a/internal/pkg/dto/response/skill_response.go +++ b/internal/pkg/dto/response/skill_response.go @@ -3,21 +3,21 @@ package response import "time" type SkillDefinitionResponse struct { - ID int64 `json:"id"` - Code string `json:"code"` - Name string `json:"name"` - Description string `json:"description"` - Instruction string `json:"instruction"` - Examples []string `json:"examples"` - AllowedToolCodes []string `json:"allowedToolCodes"` - Priority int `json:"priority"` - Status int `json:"status"` - StatusName string `json:"statusName"` - Remark string `json:"remark"` - CreatedAt time.Time `json:"createdAt"` - UpdatedAt time.Time `json:"updatedAt"` - CreateUserName string `json:"createUserName"` - UpdateUserName string `json:"updateUserName"` + ID int64 `json:"id"` + Code string `json:"code"` + Name string `json:"name"` + Description string `json:"description"` + Instruction string `json:"instruction"` + Examples []string `json:"examples"` + ToolWhitelist []string `json:"toolWhitelist"` + Priority int `json:"priority"` + Status int `json:"status"` + StatusName string `json:"statusName"` + Remark string `json:"remark"` + CreatedAt time.Time `json:"createdAt"` + UpdatedAt time.Time `json:"updatedAt"` + CreateUserName string `json:"createUserName"` + UpdateUserName string `json:"updateUserName"` } type SkillDebugRunResponse struct { diff --git a/internal/services/skill_definition_service.go b/internal/services/skill_definition_service.go index 0ff24ad..f9297ff 100644 --- a/internal/services/skill_definition_service.go +++ b/internal/services/skill_definition_service.go @@ -109,16 +109,16 @@ func (s *skillDefinitionService) CreateSkillDefinition(req request.CreateSkillDe return nil, errorsx.InvalidParam("Skill 编码已存在") } item := &models.SkillDefinition{ - Code: normalized.Code, - Name: normalized.Name, - Description: normalized.Description, - Instruction: normalized.Instruction, - Examples: mustMarshalSkillStringArray(normalized.Examples), - AllowedToolCodes: mustMarshalSkillStringArray(normalized.AllowedToolCodes), - Priority: normalized.Priority, - Status: enums.StatusOk, - Remark: normalized.Remark, - AuditFields: utils.BuildAuditFields(operator), + Code: normalized.Code, + Name: normalized.Name, + Description: normalized.Description, + Instruction: normalized.Instruction, + Examples: mustMarshalSkillStringArray(normalized.Examples), + ToolWhitelist: mustMarshalSkillStringArray(normalized.ToolWhitelist), + Priority: normalized.Priority, + Status: enums.StatusOk, + Remark: normalized.Remark, + AuditFields: utils.BuildAuditFields(operator), } if item.Priority <= 0 { item.Priority = s.NextPriority() @@ -151,9 +151,9 @@ func (s *skillDefinitionService) UpdateSkillDefinition(req request.UpdateSkillDe "code": normalized.Code, "name": normalized.Name, "description": normalized.Description, - "content": normalized.Instruction, + "instruction": normalized.Instruction, "examples": mustMarshalSkillStringArray(normalized.Examples), - "allowed_tool_codes": mustMarshalSkillStringArray(normalized.AllowedToolCodes), + "allowed_tool_codes": mustMarshalSkillStringArray(normalized.ToolWhitelist), "priority": resolveSkillPriorityForService(normalized.Priority, current.Priority), "remark": normalized.Remark, "update_user_id": operator.UserID, @@ -184,17 +184,17 @@ func (s *skillDefinitionService) normalizeSkillDefinitionRequest(req request.Cre if err != nil { return nil, err } - allowedToolCodes, err := normalizeSkillStringArray(req.AllowedToolCodes) + toolWhitelist, err := normalizeSkillStringArray(req.ToolWhitelist) if err != nil { return nil, err } - for _, toolCode := range allowedToolCodes { + for _, toolCode := range toolWhitelist { if err := ToolCatalogService.ValidateMCPToolCode(toolCode); err != nil { return nil, err } } normalized.Examples = examples - normalized.AllowedToolCodes = allowedToolCodes + normalized.ToolWhitelist = toolWhitelist return normalized, nil } diff --git a/web/app/(console)/skill-definition/_components/edit.tsx b/web/app/(console)/skill-definition/_components/edit.tsx index 0d508a7..cec58c7 100644 --- a/web/app/(console)/skill-definition/_components/edit.tsx +++ b/web/app/(console)/skill-definition/_components/edit.tsx @@ -79,7 +79,7 @@ function buildForm(item: SkillDefinition | null): EditForm { function buildPayload( form: EditForm, - allowedToolCodes: string[], + toolWhitelist: string[], ): CreateSkillDefinitionPayload { return { code: form.code.trim(), @@ -90,7 +90,7 @@ function buildPayload( .split("\n") .map((item) => item.trim()) .filter(Boolean), - allowedToolCodes, + toolWhitelist, remark: form.remark.trim(), }; } @@ -130,7 +130,7 @@ function SkillEditDialogBody({ const formId = "skill-definition-edit-form"; const [loading, setLoading] = useState(false); const [toolCatalog, setToolCatalog] = useState([]); - const [selectedAllowedToolCodes, setSelectedAllowedToolCodes] = useState< + const [selectedToolWhitelist, setSelectedToolWhitelist] = useState< string[] >([]); const [toolCodeToAdd, setToolCodeToAdd] = useState(""); @@ -154,7 +154,7 @@ function SkillEditDialogBody({ async function loadDetail() { if (!itemId) { reset(emptyForm); - setSelectedAllowedToolCodes([]); + setSelectedToolWhitelist([]); setToolCodeToAdd(""); return; } @@ -163,7 +163,7 @@ function SkillEditDialogBody({ try { const data = await fetchSkillDefinition(itemId); reset(buildForm(data)); - setSelectedAllowedToolCodes(data.allowedToolCodes ?? []); + setSelectedToolWhitelist(data.toolWhitelist ?? []); setToolCodeToAdd(""); } catch (error) { console.error("Failed to load skill definition:", error); @@ -189,7 +189,7 @@ function SkillEditDialogBody({ }, []); async function onFormSubmit(values: EditForm) { - await onSubmit(buildPayload(values, selectedAllowedToolCodes)); + await onSubmit(buildPayload(values, selectedToolWhitelist)); } const toolOptions = useMemo( @@ -204,31 +204,31 @@ function SkillEditDialogBody({ const addableToolOptions = useMemo( () => toolOptions.filter( - (option) => !selectedAllowedToolCodes.includes(option.value), + (option) => !selectedToolWhitelist.includes(option.value), ), - [selectedAllowedToolCodes, toolOptions], + [selectedToolWhitelist, toolOptions], ); const selectedToolOptions = useMemo( () => - selectedAllowedToolCodes + selectedToolWhitelist .map((toolCode) => toolOptions.find((option) => option.value === toolCode)) .filter( (option): option is { value: string; label: string } => !!option, ), - [selectedAllowedToolCodes, toolOptions], + [selectedToolWhitelist, toolOptions], ); - function handleAddAllowedTool(toolCode: string) { - if (!toolCode || selectedAllowedToolCodes.includes(toolCode)) { + function handleAddToolWhitelist(toolCode: string) { + if (!toolCode || selectedToolWhitelist.includes(toolCode)) { return; } - setSelectedAllowedToolCodes((prev) => [...prev, toolCode]); + setSelectedToolWhitelist((prev) => [...prev, toolCode]); setToolCodeToAdd(""); } - function handleRemoveAllowedTool(toolCode: string) { - setSelectedAllowedToolCodes((prev) => + function handleRemoveToolWhitelist(toolCode: string) { + setSelectedToolWhitelist((prev) => prev.filter((item) => item !== toolCode), ); } @@ -336,24 +336,24 @@ function SkillEditDialogBody({ - Allowed Tools + 工具白名单
@@ -370,7 +370,7 @@ function SkillEditDialogBody({ type="button" variant="outline" size="sm" - onClick={() => handleRemoveAllowedTool(option.value)} + onClick={() => handleRemoveToolWhitelist(option.value)} className="justify-start" > {option.label} diff --git a/web/lib/api/admin.ts b/web/lib/api/admin.ts index c67016c..1e9fe21 100644 --- a/web/lib/api/admin.ts +++ b/web/lib/api/admin.ts @@ -275,7 +275,7 @@ export type SkillDefinition = { description: string instruction: string examples: string[] - allowedToolCodes: string[] + toolWhitelist: string[] priority: number status: number statusName: string @@ -292,7 +292,7 @@ export type CreateSkillDefinitionPayload = { description: string instruction: string examples: string[] - allowedToolCodes: string[] + toolWhitelist: string[] priority?: number remark: string }