package random import ( "context" "crypto/rand" "fmt" "math/big" mathrand "math/rand" "strings" "git.yeij.top/AskaEth/Cyrene-Plugins/sdk" ) type RandomPlugin struct{ sdk.BasePlugin } func (p *RandomPlugin) Metadata() sdk.PluginMetadata { return sdk.PluginMetadata{ Name: "random", DisplayName: "Random Generator", Version: "1.0.0", Description: "Random generation: numbers, UUIDs, secure passwords, pick/shuffle", Category: "utility", Author: sdk.PluginAuthor{Name: "Cyrene Team"}, } } func (p *RandomPlugin) Tools() []sdk.Tool { return []sdk.Tool{&RandomTool{}} } type RandomTool struct{ sdk.BaseTool } func (t *RandomTool) Definition() sdk.ToolDefinition { return sdk.ToolDefinition{ ID: "random", Name: "random", DisplayName: "Random Generator", Description: "Random generation. Random numbers, UUID v4, secure passwords, pick from list, shuffle list.", Category: "utility", Complexity: sdk.ComplexitySimple, Parameters: map[string]interface{}{ "type": "object", "properties": map[string]interface{}{ "action": map[string]interface{}{"type": "string", "enum": []string{"number", "uuid", "password", "pick", "shuffle"}}, "min": map[string]interface{}{"type": "number"}, "max": map[string]interface{}{"type": "number"}, "length": map[string]interface{}{"type": "number"}, "items": map[string]interface{}{"type": "array", "items": map[string]interface{}{"type": "string"}}, "count": map[string]interface{}{"type": "number"}, }, "required": []string{"action"}, }, } } func (t *RandomTool) Validate(args map[string]interface{}) error { if _, ok := args["action"]; !ok { return fmt.Errorf("missing required parameter: action") } return nil } func (t *RandomTool) Execute(_ context.Context, args map[string]interface{}) (*sdk.ToolResult, error) { action, _ := args["action"].(string) switch action { case "number": min := getIntArg(args, "min", 0) max := getIntArg(args, "max", 100) n, err := rand.Int(rand.Reader, big.NewInt(int64(max-min+1))) if err != nil { return &sdk.ToolResult{ToolName: "random", Success: false, Error: err.Error()}, nil } return &sdk.ToolResult{ToolName: "random", Success: true, Output: fmt.Sprintf("%d", int(n.Int64())+min)}, nil case "uuid": uuid := make([]byte, 16) rand.Read(uuid) uuid[6] = (uuid[6] & 0x0f) | 0x40 uuid[8] = (uuid[8] & 0x3f) | 0x80 return &sdk.ToolResult{ToolName: "random", Success: true, Output: fmt.Sprintf("%x-%x-%x-%x-%x", uuid[0:4], uuid[4:6], uuid[6:8], uuid[8:10], uuid[10:])}, nil case "password": length := getIntArg(args, "length", 16) if length < 4 { length = 4 } if length > 128 { length = 128 } upper := "ABCDEFGHIJKLMNOPQRSTUVWXYZ" lower := "abcdefghijklmnopqrstuvwxyz" digits := "0123456789" symbols := "!@#$%^&*()_+-=[]{}|;:,.<>?" all := upper + lower + digits + symbols bytes := make([]byte, length) for i := range bytes { idx, _ := rand.Int(rand.Reader, big.NewInt(int64(len(all)))) bytes[i] = all[idx.Int64()] } return &sdk.ToolResult{ToolName: "random", Success: true, Output: string(bytes)}, nil case "pick": items := getStringSliceArg(args, "items") if len(items) == 0 { return &sdk.ToolResult{ToolName: "random", Success: false, Error: "items list is empty"}, nil } count := getIntArg(args, "count", 1) if count > len(items) { count = len(items) } indices := shuffledIndices(len(items)) picked := make([]string, count) for i := 0; i < count; i++ { picked[i] = items[indices[i]] } return &sdk.ToolResult{ToolName: "random", Success: true, Output: strings.Join(picked, ", ")}, nil case "shuffle": items := getStringSliceArg(args, "items") indices := shuffledIndices(len(items)) shuffled := make([]string, len(items)) for i, idx := range indices { shuffled[i] = items[idx] } return &sdk.ToolResult{ToolName: "random", Success: true, Output: strings.Join(shuffled, ", ")}, nil } return &sdk.ToolResult{ToolName: "random", Success: false, Error: "unknown action: " + action}, nil } func getIntArg(args map[string]interface{}, key string, defaultVal int) int { v, ok := args[key] if !ok { return defaultVal } switch n := v.(type) { case float64: return int(n) case int: return n case int64: return int(n) } return defaultVal } func getStringSliceArg(args map[string]interface{}, key string) []string { v, ok := args[key] if !ok { return nil } switch s := v.(type) { case []string: return s case []interface{}: result := make([]string, len(s)) for i, item := range s { result[i] = fmt.Sprint(item) } return result } return nil } func shuffledIndices(n int) []int { indices := make([]int, n) for i := range indices { indices[i] = i } for i := n - 1; i > 0; i-- { jBig, err := rand.Int(rand.Reader, big.NewInt(int64(i+1))) if err != nil { j := mathrand.Intn(i + 1) indices[i], indices[j] = indices[j], indices[i] continue } j := int(jBig.Int64()) indices[i], indices[j] = indices[j], indices[i] } return indices }