c94b163540
Add a public GET /api/ui/agent-starters endpoint returning localized empty-state content (title, description, preview images, and starter prompts) for the canvas Agent panel. Content is server-configurable via AgentStarter config with built-in zh-CN/en-US fallbacks, and the route is exempt from authentication so shared canvases render the same content. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
144 lines
5.3 KiB
Go
144 lines
5.3 KiB
Go
// Code scaffolded by goctl. Safe to edit.
|
|
// goctl 1.10.1
|
|
|
|
package logic
|
|
|
|
import (
|
|
"context"
|
|
"strings"
|
|
|
|
"img_infinite_canvas/internal/config"
|
|
"img_infinite_canvas/internal/svc"
|
|
"img_infinite_canvas/internal/types"
|
|
|
|
"github.com/zeromicro/go-zero/core/logx"
|
|
)
|
|
|
|
type GetAgentStarterConfigLogic struct {
|
|
logx.Logger
|
|
ctx context.Context
|
|
svcCtx *svc.ServiceContext
|
|
}
|
|
|
|
func NewGetAgentStarterConfigLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetAgentStarterConfigLogic {
|
|
return &GetAgentStarterConfigLogic{
|
|
Logger: logx.WithContext(ctx),
|
|
ctx: ctx,
|
|
svcCtx: svcCtx,
|
|
}
|
|
}
|
|
|
|
func (l *GetAgentStarterConfigLogic) GetAgentStarterConfig(req *types.GetAgentStarterConfigRequest) (resp *types.AgentStarterConfigResponse, err error) {
|
|
locale := "zh-CN"
|
|
if req != nil && strings.EqualFold(strings.TrimSpace(req.Locale), "en-US") {
|
|
locale = "en-US"
|
|
}
|
|
content := resolveAgentStarterLocale(l.svcCtx.Config.AgentStarter, locale)
|
|
|
|
return &types.AgentStarterConfigResponse{
|
|
Title: content.Title,
|
|
Description: content.Description,
|
|
PreviewImages: resolveAgentStarterImages(l.svcCtx.Config.AgentStarter.PreviewImages),
|
|
Starters: toAgentStarterItems(content.Starters),
|
|
}, nil
|
|
}
|
|
|
|
var defaultAgentStarterImages = []string{
|
|
"https://static.codia.ai/public/images/f788bdcc/lg.webp",
|
|
"https://static.codia.ai/public/images/ec25067a/lg.webp",
|
|
"https://static.codia.ai/public/images/d4ccbe39/lg.webp",
|
|
}
|
|
|
|
var defaultAgentStarterPrompts = []config.AgentStarterItemConfig{
|
|
{ID: "ecommerce", Label: "电商商品图", Prompt: "Create a premium ecommerce product image for a portable espresso machine, with realistic lighting, clean composition, benefit callouts, and marketplace-ready visual hierarchy"},
|
|
{ID: "poster", Label: "海报", Prompt: "Design a bold launch poster for a new skincare product line, with strong typography, product focus, campaign headline, date, and a polished premium layout"},
|
|
{ID: "brand-visual", Label: "品牌视觉", Prompt: "Create a brand identity direction for a modern wellness drink brand, including color palette, typography mood, logo usage, packaging accents, and social-ready visual elements"},
|
|
{ID: "social-media", Label: "社交媒体", Prompt: "Create a square Instagram promotion for a weekend fashion sale, with product cutouts, discount headline, brand colors, and a layout that works as a paid social ad"},
|
|
{ID: "logo", Label: "Logo 设计", Prompt: "Design a clean vector logo for a direct-to-consumer home goods brand named Loom & Line, with a simple mark, balanced wordmark, and clear black-and-white usage"},
|
|
}
|
|
|
|
func resolveAgentStarterLocale(options config.AgentStarterConfig, locale string) config.AgentStarterLocaleConfig {
|
|
fallback := config.AgentStarterLocaleConfig{
|
|
Title: "今天想创作什么?",
|
|
Description: "输入提示词开始——或使用下方的起点",
|
|
Starters: defaultAgentStarterPrompts,
|
|
}
|
|
configured := options.ZhCN
|
|
if locale == "en-US" {
|
|
fallback.Title = "What would you like to create today?"
|
|
fallback.Description = "Enter a prompt to begin, or use one of the starting points below."
|
|
fallback.Starters = englishAgentStarterPrompts(defaultAgentStarterPrompts)
|
|
configured = options.EnUS
|
|
}
|
|
|
|
if title := strings.TrimSpace(configured.Title); title != "" {
|
|
fallback.Title = title
|
|
}
|
|
if description := strings.TrimSpace(configured.Description); description != "" {
|
|
fallback.Description = description
|
|
}
|
|
if starters := validAgentStarterConfigs(configured.Starters); len(starters) > 0 {
|
|
fallback.Starters = starters
|
|
}
|
|
return fallback
|
|
}
|
|
|
|
func englishAgentStarterPrompts(items []config.AgentStarterItemConfig) []config.AgentStarterItemConfig {
|
|
labels := map[string]string{
|
|
"ecommerce": "E-commerce product",
|
|
"poster": "Poster",
|
|
"brand-visual": "Brand visual",
|
|
"social-media": "Social media",
|
|
"logo": "Logo design",
|
|
}
|
|
result := make([]config.AgentStarterItemConfig, 0, len(items))
|
|
for _, item := range items {
|
|
item.Label = labels[item.ID]
|
|
result = append(result, item)
|
|
}
|
|
return result
|
|
}
|
|
|
|
func resolveAgentStarterImages(configured []string) []string {
|
|
images := make([]string, 0, len(configured))
|
|
for _, image := range configured {
|
|
if image = strings.TrimSpace(image); image != "" {
|
|
images = append(images, image)
|
|
}
|
|
if len(images) == 3 {
|
|
break
|
|
}
|
|
}
|
|
if len(images) == 0 {
|
|
return append([]string(nil), defaultAgentStarterImages...)
|
|
}
|
|
return images
|
|
}
|
|
|
|
func validAgentStarterConfigs(configured []config.AgentStarterItemConfig) []config.AgentStarterItemConfig {
|
|
starters := make([]config.AgentStarterItemConfig, 0, len(configured))
|
|
seen := make(map[string]struct{}, len(configured))
|
|
for _, item := range configured {
|
|
item.ID = strings.TrimSpace(item.ID)
|
|
item.Label = strings.TrimSpace(item.Label)
|
|
item.Prompt = strings.TrimSpace(item.Prompt)
|
|
if item.ID == "" || item.Label == "" || item.Prompt == "" {
|
|
continue
|
|
}
|
|
if _, exists := seen[item.ID]; exists {
|
|
continue
|
|
}
|
|
seen[item.ID] = struct{}{}
|
|
starters = append(starters, item)
|
|
}
|
|
return starters
|
|
}
|
|
|
|
func toAgentStarterItems(configured []config.AgentStarterItemConfig) []types.AgentStarterItem {
|
|
items := make([]types.AgentStarterItem, 0, len(configured))
|
|
for _, item := range configured {
|
|
items = append(items, types.AgentStarterItem{Id: item.ID, Label: item.Label, Prompt: item.Prompt})
|
|
}
|
|
return items
|
|
}
|