feat: 增加技能参考和模板的创建、获取及保存功能
This commit is contained in:
parent
52cd5e72ab
commit
670aff79cc
|
|
@ -125,6 +125,76 @@ func (s *SkillsApi) SaveResource(c *gin.Context) {
|
|||
response.OkWithMessage("保存成功", c)
|
||||
}
|
||||
|
||||
func (s *SkillsApi) CreateReference(c *gin.Context) {
|
||||
var req request.SkillReferenceCreateRequest
|
||||
_ = c.ShouldBindJSON(&req)
|
||||
fileName, content, err := skillsService.CreateReference(c.Request.Context(), req)
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("创建参考失败", zap.Error(err))
|
||||
response.FailWithMessage("创建参考失败", c)
|
||||
return
|
||||
}
|
||||
response.OkWithDetailed(gin.H{"fileName": fileName, "content": content}, "创建成功", c)
|
||||
}
|
||||
|
||||
func (s *SkillsApi) GetReference(c *gin.Context) {
|
||||
var req request.SkillFileRequest
|
||||
_ = c.ShouldBindJSON(&req)
|
||||
content, err := skillsService.GetReference(c.Request.Context(), req)
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("读取参考失败", zap.Error(err))
|
||||
response.FailWithMessage("读取参考失败", c)
|
||||
return
|
||||
}
|
||||
response.OkWithDetailed(gin.H{"content": content}, "获取成功", c)
|
||||
}
|
||||
|
||||
func (s *SkillsApi) SaveReference(c *gin.Context) {
|
||||
var req request.SkillFileSaveRequest
|
||||
_ = c.ShouldBindJSON(&req)
|
||||
if err := skillsService.SaveReference(c.Request.Context(), req); err != nil {
|
||||
global.GVA_LOG.Error("保存参考失败", zap.Error(err))
|
||||
response.FailWithMessage("保存参考失败", c)
|
||||
return
|
||||
}
|
||||
response.OkWithMessage("保存成功", c)
|
||||
}
|
||||
|
||||
func (s *SkillsApi) CreateTemplate(c *gin.Context) {
|
||||
var req request.SkillTemplateCreateRequest
|
||||
_ = c.ShouldBindJSON(&req)
|
||||
fileName, content, err := skillsService.CreateTemplate(c.Request.Context(), req)
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("创建模板失败", zap.Error(err))
|
||||
response.FailWithMessage("创建模板失败", c)
|
||||
return
|
||||
}
|
||||
response.OkWithDetailed(gin.H{"fileName": fileName, "content": content}, "创建成功", c)
|
||||
}
|
||||
|
||||
func (s *SkillsApi) GetTemplate(c *gin.Context) {
|
||||
var req request.SkillFileRequest
|
||||
_ = c.ShouldBindJSON(&req)
|
||||
content, err := skillsService.GetTemplate(c.Request.Context(), req)
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("读取模板失败", zap.Error(err))
|
||||
response.FailWithMessage("读取模板失败", c)
|
||||
return
|
||||
}
|
||||
response.OkWithDetailed(gin.H{"content": content}, "获取成功", c)
|
||||
}
|
||||
|
||||
func (s *SkillsApi) SaveTemplate(c *gin.Context) {
|
||||
var req request.SkillFileSaveRequest
|
||||
_ = c.ShouldBindJSON(&req)
|
||||
if err := skillsService.SaveTemplate(c.Request.Context(), req); err != nil {
|
||||
global.GVA_LOG.Error("保存模板失败", zap.Error(err))
|
||||
response.FailWithMessage("保存模板失败", c)
|
||||
return
|
||||
}
|
||||
response.OkWithMessage("保存成功", c)
|
||||
}
|
||||
|
||||
func (s *SkillsApi) GetGlobalConstraint(c *gin.Context) {
|
||||
var req request.SkillToolRequest
|
||||
_ = c.ShouldBindJSON(&req)
|
||||
|
|
|
|||
|
|
@ -32,6 +32,18 @@ type SkillResourceCreateRequest struct {
|
|||
FileName string `json:"fileName"`
|
||||
}
|
||||
|
||||
type SkillReferenceCreateRequest struct {
|
||||
Tool string `json:"tool"`
|
||||
Skill string `json:"skill"`
|
||||
FileName string `json:"fileName"`
|
||||
}
|
||||
|
||||
type SkillTemplateCreateRequest struct {
|
||||
Tool string `json:"tool"`
|
||||
Skill string `json:"skill"`
|
||||
FileName string `json:"fileName"`
|
||||
}
|
||||
|
||||
type SkillFileRequest struct {
|
||||
Tool string `json:"tool"`
|
||||
Skill string `json:"skill"`
|
||||
|
|
|
|||
|
|
@ -15,6 +15,8 @@ type SkillDetail struct {
|
|||
Markdown string `json:"markdown"`
|
||||
Scripts []string `json:"scripts"`
|
||||
Resources []string `json:"resources"`
|
||||
References []string `json:"references"`
|
||||
Templates []string `json:"templates"`
|
||||
}
|
||||
|
||||
type SkillTool struct {
|
||||
|
|
|
|||
|
|
@ -17,6 +17,12 @@ func (s *SkillsRouter) InitSkillsRouter(Router *gin.RouterGroup) {
|
|||
skillsRouter.POST("createResource", skillsApi.CreateResource)
|
||||
skillsRouter.POST("getResource", skillsApi.GetResource)
|
||||
skillsRouter.POST("saveResource", skillsApi.SaveResource)
|
||||
skillsRouter.POST("createReference", skillsApi.CreateReference)
|
||||
skillsRouter.POST("getReference", skillsApi.GetReference)
|
||||
skillsRouter.POST("saveReference", skillsApi.SaveReference)
|
||||
skillsRouter.POST("createTemplate", skillsApi.CreateTemplate)
|
||||
skillsRouter.POST("getTemplate", skillsApi.GetTemplate)
|
||||
skillsRouter.POST("saveTemplate", skillsApi.SaveTemplate)
|
||||
skillsRouter.POST("getGlobalConstraint", skillsApi.GetGlobalConstraint)
|
||||
skillsRouter.POST("saveGlobalConstraint", skillsApi.SaveGlobalConstraint)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,6 +43,10 @@ const defaultSkillMarkdown = "## 技能用途\n请在这里描述技能的目标
|
|||
|
||||
const defaultResourceMarkdown = "# 资源说明\n请在这里补充资源内容。\n"
|
||||
|
||||
const defaultReferenceMarkdown = "# 参考资料\n请在这里补充参考资料内容。\n"
|
||||
|
||||
const defaultTemplateMarkdown = "# 模板\n请在这里补充模板内容。\n"
|
||||
|
||||
const defaultGlobalConstraintMarkdown = "# 全局约束\n请在这里补充该工具的统一约束与使用规范。\n"
|
||||
|
||||
type SkillsService struct{}
|
||||
|
|
@ -113,6 +117,8 @@ func (s *SkillsService) Detail(_ context.Context, tool, skill string) (system.Sk
|
|||
|
||||
detail.Scripts = listFiles(filepath.Join(skillDir, "scripts"))
|
||||
detail.Resources = listFiles(filepath.Join(skillDir, "resources"))
|
||||
detail.References = listFiles(filepath.Join(skillDir, "references"))
|
||||
detail.Templates = listFiles(filepath.Join(skillDir, "templates"))
|
||||
return detail, nil
|
||||
}
|
||||
|
||||
|
|
@ -190,29 +196,7 @@ func (s *SkillsService) SaveScript(_ context.Context, req request.SkillFileSaveR
|
|||
}
|
||||
|
||||
func (s *SkillsService) CreateResource(_ context.Context, req request.SkillResourceCreateRequest) (string, string, error) {
|
||||
if !isSafeName(req.Skill) {
|
||||
return "", "", errors.New("技能名称不合法")
|
||||
}
|
||||
fileName, err := buildResourceFileName(req.FileName)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
skillDir, err := s.ensureSkillDir(req.Tool, req.Skill)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
filePath := filepath.Join(skillDir, "resources", fileName)
|
||||
if _, err := os.Stat(filePath); err == nil {
|
||||
return "", "", errors.New("资源已存在")
|
||||
}
|
||||
if err := os.MkdirAll(filepath.Dir(filePath), os.ModePerm); err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
content := defaultResourceMarkdown
|
||||
if err := os.WriteFile(filePath, []byte(content), 0644); err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
return fileName, content, nil
|
||||
return s.createMarkdownFile(req.Tool, req.Skill, "resources", req.FileName, defaultResourceMarkdown, "资源")
|
||||
}
|
||||
|
||||
func (s *SkillsService) GetResource(_ context.Context, req request.SkillFileRequest) (string, error) {
|
||||
|
|
@ -223,6 +207,30 @@ func (s *SkillsService) SaveResource(_ context.Context, req request.SkillFileSav
|
|||
return s.writeSkillFile(req.Tool, req.Skill, "resources", req.FileName, req.Content)
|
||||
}
|
||||
|
||||
func (s *SkillsService) CreateReference(_ context.Context, req request.SkillReferenceCreateRequest) (string, string, error) {
|
||||
return s.createMarkdownFile(req.Tool, req.Skill, "references", req.FileName, defaultReferenceMarkdown, "参考")
|
||||
}
|
||||
|
||||
func (s *SkillsService) GetReference(_ context.Context, req request.SkillFileRequest) (string, error) {
|
||||
return s.readSkillFile(req.Tool, req.Skill, "references", req.FileName)
|
||||
}
|
||||
|
||||
func (s *SkillsService) SaveReference(_ context.Context, req request.SkillFileSaveRequest) error {
|
||||
return s.writeSkillFile(req.Tool, req.Skill, "references", req.FileName, req.Content)
|
||||
}
|
||||
|
||||
func (s *SkillsService) CreateTemplate(_ context.Context, req request.SkillTemplateCreateRequest) (string, string, error) {
|
||||
return s.createMarkdownFile(req.Tool, req.Skill, "templates", req.FileName, defaultTemplateMarkdown, "模板")
|
||||
}
|
||||
|
||||
func (s *SkillsService) GetTemplate(_ context.Context, req request.SkillFileRequest) (string, error) {
|
||||
return s.readSkillFile(req.Tool, req.Skill, "templates", req.FileName)
|
||||
}
|
||||
|
||||
func (s *SkillsService) SaveTemplate(_ context.Context, req request.SkillFileSaveRequest) error {
|
||||
return s.writeSkillFile(req.Tool, req.Skill, "templates", req.FileName, req.Content)
|
||||
}
|
||||
|
||||
func (s *SkillsService) GetGlobalConstraint(_ context.Context, tool string) (string, bool, error) {
|
||||
skillsDir, err := s.toolSkillsDir(tool)
|
||||
if err != nil {
|
||||
|
|
@ -309,6 +317,35 @@ func (s *SkillsService) ensureSkillDir(tool, skill string) (string, error) {
|
|||
return skillDir, nil
|
||||
}
|
||||
|
||||
func (s *SkillsService) createMarkdownFile(tool, skill, subDir, fileName, defaultContent, label string) (string, string, error) {
|
||||
if !isSafeName(skill) {
|
||||
return "", "", errors.New("技能名称不合法")
|
||||
}
|
||||
cleanName, err := buildResourceFileName(fileName)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
skillDir, err := s.ensureSkillDir(tool, skill)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
filePath := filepath.Join(skillDir, subDir, cleanName)
|
||||
if _, err := os.Stat(filePath); err == nil {
|
||||
if label == "" {
|
||||
label = "文件"
|
||||
}
|
||||
return "", "", fmt.Errorf("%s已存在", label)
|
||||
}
|
||||
if err := os.MkdirAll(filepath.Dir(filePath), os.ModePerm); err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
content := defaultContent
|
||||
if err := os.WriteFile(filePath, []byte(content), 0644); err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
return cleanName, content, nil
|
||||
}
|
||||
|
||||
func (s *SkillsService) readSkillFile(tool, skill, subDir, fileName string) (string, error) {
|
||||
if !isSafeName(skill) {
|
||||
return "", errors.New("技能名称不合法")
|
||||
|
|
|
|||
|
|
@ -124,6 +124,12 @@ func (i *initApi) InitializeData(ctx context.Context) (context.Context, error) {
|
|||
{ApiGroup: "skills", Method: "POST", Path: "/skills/createResource", Description: "创建技能资源"},
|
||||
{ApiGroup: "skills", Method: "POST", Path: "/skills/getResource", Description: "读取技能资源"},
|
||||
{ApiGroup: "skills", Method: "POST", Path: "/skills/saveResource", Description: "保存技能资源"},
|
||||
{ApiGroup: "skills", Method: "POST", Path: "/skills/createReference", Description: "创建技能参考"},
|
||||
{ApiGroup: "skills", Method: "POST", Path: "/skills/getReference", Description: "读取技能参考"},
|
||||
{ApiGroup: "skills", Method: "POST", Path: "/skills/saveReference", Description: "保存技能参考"},
|
||||
{ApiGroup: "skills", Method: "POST", Path: "/skills/createTemplate", Description: "创建技能模板"},
|
||||
{ApiGroup: "skills", Method: "POST", Path: "/skills/getTemplate", Description: "读取技能模板"},
|
||||
{ApiGroup: "skills", Method: "POST", Path: "/skills/saveTemplate", Description: "保存技能模板"},
|
||||
{ApiGroup: "skills", Method: "POST", Path: "/skills/getGlobalConstraint", Description: "读取全局约束"},
|
||||
{ApiGroup: "skills", Method: "POST", Path: "/skills/saveGlobalConstraint", Description: "保存全局约束"},
|
||||
|
||||
|
|
|
|||
|
|
@ -126,6 +126,12 @@ func (i *initCasbin) InitializeData(ctx context.Context) (context.Context, error
|
|||
{Ptype: "p", V0: "888", V1: "/skills/createResource", V2: "POST"},
|
||||
{Ptype: "p", V0: "888", V1: "/skills/getResource", V2: "POST"},
|
||||
{Ptype: "p", V0: "888", V1: "/skills/saveResource", V2: "POST"},
|
||||
{Ptype: "p", V0: "888", V1: "/skills/createReference", V2: "POST"},
|
||||
{Ptype: "p", V0: "888", V1: "/skills/getReference", V2: "POST"},
|
||||
{Ptype: "p", V0: "888", V1: "/skills/saveReference", V2: "POST"},
|
||||
{Ptype: "p", V0: "888", V1: "/skills/createTemplate", V2: "POST"},
|
||||
{Ptype: "p", V0: "888", V1: "/skills/getTemplate", V2: "POST"},
|
||||
{Ptype: "p", V0: "888", V1: "/skills/saveTemplate", V2: "POST"},
|
||||
{Ptype: "p", V0: "888", V1: "/skills/getGlobalConstraint", V2: "POST"},
|
||||
{Ptype: "p", V0: "888", V1: "/skills/saveGlobalConstraint", V2: "POST"},
|
||||
|
||||
|
|
|
|||
|
|
@ -79,6 +79,54 @@ export const saveSkillResource = (data) => {
|
|||
})
|
||||
}
|
||||
|
||||
export const createSkillReference = (data) => {
|
||||
return service({
|
||||
url: '/skills/createReference',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export const getSkillReference = (data) => {
|
||||
return service({
|
||||
url: '/skills/getReference',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export const saveSkillReference = (data) => {
|
||||
return service({
|
||||
url: '/skills/saveReference',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export const createSkillTemplate = (data) => {
|
||||
return service({
|
||||
url: '/skills/createTemplate',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export const getSkillTemplate = (data) => {
|
||||
return service({
|
||||
url: '/skills/getTemplate',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export const saveSkillTemplate = (data) => {
|
||||
return service({
|
||||
url: '/skills/saveTemplate',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export const getGlobalConstraint = (data) => {
|
||||
return service({
|
||||
url: '/skills/getGlobalConstraint',
|
||||
|
|
|
|||
Loading…
Reference in New Issue