| 199 | } |
| 200 | |
| 201 | func testToolWithLoader(t *Tool, lang string, loadTool func(owner string, name string) (*Tool, error)) (string, error) { |
| 202 | if t.ClientSecret == "***" { |
| 203 | if strings.TrimSpace(t.Owner) == "" || strings.TrimSpace(t.Name) == "" { |
| 204 | return "", fmt.Errorf("cannot restore masked tool secret without owner and name") |
| 205 | } |
| 206 | toolDb, err := loadTool(t.Owner, t.Name) |
| 207 | if err != nil { |
| 208 | return "", err |
| 209 | } |
| 210 | if toolDb == nil { |
| 211 | return "", fmt.Errorf("tool not found: %s/%s", t.Owner, t.Name) |
| 212 | } |
| 213 | t.ClientSecret = toolDb.ClientSecret |
| 214 | if t.ClientSecret == "" || t.ClientSecret == "***" { |
| 215 | return "", fmt.Errorf("masked clientSecret could not be restored") |
| 216 | } |
| 217 | } |
| 218 | |
| 219 | var payload struct { |
| 220 | Tool string `json:"tool"` |
| 221 | Arguments map[string]interface{} `json:"arguments"` |
| 222 | } |
| 223 | if err := json.Unmarshal([]byte(t.TestContent), &payload); err != nil { |
| 224 | return "", fmt.Errorf(i18n.Translate(lang, "object:invalid tool test JSON in testContent: %v"), err) |
| 225 | } |
| 226 | if strings.TrimSpace(payload.Tool) == "" { |
| 227 | return "", fmt.Errorf(i18n.Translate(lang, "object:tool test JSON must include non-empty \"tool\"")) |
| 228 | } |
| 229 | if payload.Arguments == nil { |
| 230 | payload.Arguments = map[string]interface{}{} |
| 231 | } |
| 232 | |
| 233 | owner := strings.TrimSpace(t.Owner) |
| 234 | if owner == "" { |
| 235 | return "", fmt.Errorf("tool owner is required") |
| 236 | } |
| 237 | |
| 238 | tp, err := tool.New(getToolConfig(t), lang) |
| 239 | if err != nil { |
| 240 | return "", err |
| 241 | } |
| 242 | |
| 243 | var foundTool interface { |
| 244 | Execute(ctx context.Context, arguments map[string]interface{}) (*protocol.CallToolResult, error) |
| 245 | } |
| 246 | for _, bt := range tp.BuiltinTools() { |
| 247 | if bt.GetName() == payload.Tool { |
| 248 | foundTool = wrapSnapshotBuiltin(owner, bt) |
| 249 | break |
| 250 | } |
| 251 | } |
| 252 | if foundTool == nil { |
| 253 | return "", fmt.Errorf("tool not found: %s", payload.Tool) |
| 254 | } |
| 255 | |
| 256 | result, err := foundTool.Execute(context.Background(), payload.Arguments) |
| 257 | if err != nil { |
| 258 | return "", err |