选择性整合 #547,保留主分支节点与工具条设计。新增默认折叠的节点、资产、任务和历史面板,风格与预设保留在节点内,移除重复入口。 补齐工具权限、提示词解析、资源引用保护及数据库迁移,修复提示词清空和连续编辑后的生成配置同步。 验证:前端全量 1925 项测试、构建、类型检查及 lint 通过;后端 go test ./... 通过。真实模型、PostgreSQL 实库与登录态页面验收仍待进行。 Refs #547 Co-authored-by: bensharp <bensharp@qq.com>
52 lines
1.8 KiB
Go
52 lines
1.8 KiB
Go
package tools
|
|
|
|
import (
|
|
"regexp"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"infinite-canvas/backend/internal/kernel"
|
|
)
|
|
|
|
var toolMentionPattern = regexp.MustCompile(`@\[tool:(style|motion|nine_grid|effect):(\d+):[^:\]]+:[^\]]+\]`)
|
|
|
|
// ResolveToolMentionTokens validates every tool before expanding it. Labels and
|
|
// icons are presentation only; neither grants access to a private tool.
|
|
func (s *Service) ResolveToolMentionTokens(userID, mode, prompt string) (string, error) {
|
|
if !strings.Contains(prompt, "@[tool:") {
|
|
return prompt, nil
|
|
}
|
|
if strings.TrimSpace(userID) == "" {
|
|
return "", kernel.Unauthorized("请先登录")
|
|
}
|
|
if strings.Contains(toolMentionPattern.ReplaceAllString(prompt, ""), "@[tool:") {
|
|
return "", kernel.BadAuthRequest("工具标签无效,请重新选择工具")
|
|
}
|
|
prompts := make(map[string]string)
|
|
for _, match := range toolMentionPattern.FindAllStringSubmatch(prompt, -1) {
|
|
if _, ok := prompts[match[0]]; ok {
|
|
continue
|
|
}
|
|
id, err := strconv.ParseInt(match[2], 10, 64)
|
|
if err != nil || id <= 0 {
|
|
return "", kernel.BadAuthRequest("工具 ID 无效")
|
|
}
|
|
tool, err := s.repo.ToolForUser(userID, id)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
if !tool.Enabled || tool.Type != match[1] {
|
|
return "", kernel.BadAuthRequest("工具已停用或类型不匹配")
|
|
}
|
|
imageTool := tool.Type == ToolTypeStyle || tool.Type == ToolTypeNineGrid
|
|
if (imageTool && mode != "image") || (!imageTool && mode != "video") {
|
|
return "", kernel.BadAuthRequest("工具不适用于当前生成类型")
|
|
}
|
|
if strings.TrimSpace(tool.Prompt) == "" || strings.Contains(tool.Prompt, "@[tool:") {
|
|
return "", kernel.BadAuthRequest("工具提示词为空或包含嵌套工具标签")
|
|
}
|
|
prompts[match[0]] = tool.Prompt
|
|
}
|
|
return toolMentionPattern.ReplaceAllStringFunc(prompt, func(token string) string { return prompts[token] }), nil
|
|
}
|