// Package avatar provides pure types and URL builders for avatar image providers. // No I/O — only data transformations. package avatar import ( "fmt" "net/url" ) // Provider identifies an avatar generation service. type Provider string const ( // ProviderDiceBear generates illustrated avatars via DiceBear API. // Styles: adventurer, avataaars, bottts, fun-emoji, identicon, initials, // lorelei, micah, miniavs, notionists, open-peeps, personas, pixel-art, shapes, thumbs. ProviderDiceBear Provider = "dicebear" // ProviderRoboHash generates robot/monster/head images from any text. // Sets: set1 (robots), set2 (monsters), set3 (heads), set4 (cats), set5 (humans). ProviderRoboHash Provider = "robohash" // ProviderMultiavatar generates unique multicultural avatars from a string. ProviderMultiavatar Provider = "multiavatar" ) // DiceBearStyle is a style option for the DiceBear provider. type DiceBearStyle string const ( DiceBearBottts DiceBearStyle = "bottts" DiceBearPixelArt DiceBearStyle = "pixel-art" DiceBearAdventurer DiceBearStyle = "adventurer" DiceBearShapes DiceBearStyle = "shapes" DiceBearFunEmoji DiceBearStyle = "fun-emoji" DiceBearIdenticon DiceBearStyle = "identicon" DiceBearThumbs DiceBearStyle = "thumbs" ) // RoboHashSet is a set option for the RoboHash provider. type RoboHashSet string const ( RoboHashRobots RoboHashSet = "set1" RoboHashMonsters RoboHashSet = "set2" RoboHashHeads RoboHashSet = "set3" RoboHashCats RoboHashSet = "set4" RoboHashHumans RoboHashSet = "set5" ) // Options configures avatar generation. type Options struct { // Size in pixels (square). Default: 256. Size int // DiceBear-specific style. Default: bottts. DiceBearStyle DiceBearStyle // RoboHash-specific set. Default: set1 (robots). RoboHashSet RoboHashSet } // DefaultOptions returns sensible defaults for bot avatars. func DefaultOptions() Options { return Options{ Size: 256, DiceBearStyle: DiceBearBottts, RoboHashSet: RoboHashRobots, } } // URL returns the avatar image URL for the given provider and seed (typically the agent name/ID). // Pure function — no I/O. func URL(provider Provider, seed string, opts Options) string { if opts.Size <= 0 { opts.Size = 256 } encoded := url.PathEscape(seed) switch provider { case ProviderDiceBear: style := opts.DiceBearStyle if style == "" { style = DiceBearBottts } return fmt.Sprintf("https://api.dicebear.com/9.x/%s/png?seed=%s&size=%d", style, url.QueryEscape(seed), opts.Size) case ProviderRoboHash: set := opts.RoboHashSet if set == "" { set = RoboHashRobots } return fmt.Sprintf("https://robohash.org/%s.png?set=%s&size=%dx%d", encoded, set, opts.Size, opts.Size) case ProviderMultiavatar: return fmt.Sprintf("https://api.multiavatar.com/%s.png?apikey=Wookie", encoded) default: return URL(ProviderDiceBear, seed, opts) } } // AllProviders returns the list of supported providers. func AllProviders() []Provider { return []Provider{ProviderDiceBear, ProviderRoboHash, ProviderMultiavatar} }