feat(server): wire quality/count params and layered document generator

Map imageQuality/imageCount and output_format across the HTTP and
WebSocket handlers, pass them into the design service calls, and register
the layered document generator in the service context.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-09 20:43:20 +08:00
parent 41208e566c
commit f0ae237da5
7 changed files with 43 additions and 18 deletions
@@ -57,6 +57,8 @@ type socketStartData struct {
EnableWebSearch bool `json:"enable_web_search"` EnableWebSearch bool `json:"enable_web_search"`
ImageModel string `json:"image_model"` ImageModel string `json:"image_model"`
ImageSize string `json:"image_size"` ImageSize string `json:"image_size"`
ImageQuality string `json:"image_quality"`
ImageCount int `json:"image_count"`
Mode string `json:"mode"` Mode string `json:"mode"`
} }
@@ -177,6 +179,8 @@ func (data socketStartData) toDomainChat(projectID string) design.AgentChatReque
EnableWebSearch: data.EnableWebSearch || hasSocketPreferredToolCategory(data.ToolConfig.PreferToolCategories, "SEARCH"), EnableWebSearch: data.EnableWebSearch || hasSocketPreferredToolCategory(data.ToolConfig.PreferToolCategories, "SEARCH"),
ImageModel: data.ImageModel, ImageModel: data.ImageModel,
ImageSize: data.ImageSize, ImageSize: data.ImageSize,
ImageQuality: data.ImageQuality,
ImageCount: data.ImageCount,
Mode: data.Mode, Mode: data.Mode,
} }
} }
@@ -31,7 +31,7 @@ func (l *CreateProjectAsyncLogic) CreateProjectAsync(req *types.CreateProjectReq
return nil, err return nil, err
} }
project, err := l.svcCtx.DesignService.CreateProjectAsync(l.ctx, req.Title, req.Prompt, req.ImageModel, req.ImageSize, req.EnableWebSearch) project, err := l.svcCtx.DesignService.CreateProjectAsync(l.ctx, req.Title, req.Prompt, req.ImageModel, req.ImageSize, req.ImageQuality, int(req.ImageCount), req.EnableWebSearch)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -31,7 +31,7 @@ func (l *CreateProjectLogic) CreateProject(req *types.CreateProjectRequest) (res
return nil, err return nil, err
} }
project, err := l.svcCtx.DesignService.CreateProject(l.ctx, req.Title, req.Prompt, req.ImageModel, req.ImageSize, req.EnableWebSearch) project, err := l.svcCtx.DesignService.CreateProject(l.ctx, req.Title, req.Prompt, req.ImageModel, req.ImageSize, req.ImageQuality, int(req.ImageCount), req.EnableWebSearch)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -31,7 +31,7 @@ func (l *GenerateProjectAsyncLogic) GenerateProjectAsync(req *types.GenerateRequ
return nil, err return nil, err
} }
project, err := l.svcCtx.DesignService.GenerateAsync(l.ctx, req.Id, req.Prompt, req.Mode, req.ImageModel, req.ImageSize) project, err := l.svcCtx.DesignService.GenerateAsync(l.ctx, req.Id, req.Prompt, req.Mode, req.ImageModel, req.ImageSize, req.ImageQuality, int(req.ImageCount))
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -31,7 +31,7 @@ func (l *GenerateProjectLogic) GenerateProject(req *types.GenerateRequest) (resp
return nil, err return nil, err
} }
result, err := l.svcCtx.DesignService.Generate(l.ctx, req.Id, req.Prompt, req.Mode, req.ImageModel, req.ImageSize) result, err := l.svcCtx.DesignService.Generate(l.ctx, req.Id, req.Prompt, req.Mode, req.ImageModel, req.ImageSize, req.ImageQuality, int(req.ImageCount))
if err != nil { if err != nil {
return nil, err return nil, err
} }
+18 -14
View File
@@ -33,25 +33,27 @@ func toGeneratorTaskResponse(task design.GeneratorTask) *types.GeneratorTaskResp
func toAPIGeneratorTaskInputArgs(input design.GeneratorTaskInputArgs) types.GeneratorTaskInputArgs { func toAPIGeneratorTaskInputArgs(input design.GeneratorTaskInputArgs) types.GeneratorTaskInputArgs {
return types.GeneratorTaskInputArgs{ return types.GeneratorTaskInputArgs{
AspectRatio: input.AspectRatio, AspectRatio: input.AspectRatio,
Image: append([]string(nil), input.Image...), Image: append([]string(nil), input.Image...),
ImageUrl: input.ImageURL, ImageUrl: input.ImageURL,
Prompt: input.Prompt, OutputFormat: input.OutputFormat,
Resolution: input.Resolution, Prompt: input.Prompt,
SrcBox: toAPINormalizedBoxPtr(input.SrcBox), Resolution: input.Resolution,
DstBox: toAPINormalizedBoxPtr(input.DstBox), SrcBox: toAPINormalizedBoxPtr(input.SrcBox),
DstBox: toAPINormalizedBoxPtr(input.DstBox),
} }
} }
func toDomainGeneratorTaskInputArgs(input types.GeneratorTaskInputArgs) design.GeneratorTaskInputArgs { func toDomainGeneratorTaskInputArgs(input types.GeneratorTaskInputArgs) design.GeneratorTaskInputArgs {
return design.GeneratorTaskInputArgs{ return design.GeneratorTaskInputArgs{
AspectRatio: input.AspectRatio, AspectRatio: input.AspectRatio,
Image: append([]string(nil), input.Image...), Image: append([]string(nil), input.Image...),
ImageURL: input.ImageUrl, ImageURL: input.ImageUrl,
Prompt: input.Prompt, OutputFormat: input.OutputFormat,
Resolution: input.Resolution, Prompt: input.Prompt,
SrcBox: toDomainNormalizedBoxPtr(input.SrcBox), Resolution: input.Resolution,
DstBox: toDomainNormalizedBoxPtr(input.DstBox), SrcBox: toDomainNormalizedBoxPtr(input.SrcBox),
DstBox: toDomainNormalizedBoxPtr(input.DstBox),
} }
} }
@@ -546,6 +548,8 @@ func toDomainAgentChat(req *types.AgentChatRequest) design.AgentChatRequest {
EnableWebSearch: req.EnableWebSearch || hasPreferredToolCategory(req.ToolConfig.PreferToolCategories.Search), EnableWebSearch: req.EnableWebSearch || hasPreferredToolCategory(req.ToolConfig.PreferToolCategories.Search),
ImageModel: req.ImageModel, ImageModel: req.ImageModel,
ImageSize: req.ImageSize, ImageSize: req.ImageSize,
ImageQuality: req.ImageQuality,
ImageCount: int(req.ImageCount),
Mode: req.Mode, Mode: req.Mode,
} }
} }
+17
View File
@@ -59,6 +59,7 @@ func NewServiceContext(c config.Config) *ServiceContext {
textExtractor := newTextExtractor(c) textExtractor := newTextExtractor(c)
service := application.NewDesignService(repo, agentRunner, assets, researcher, textExtractor, creativeAgent) service := application.NewDesignService(repo, agentRunner, assets, researcher, textExtractor, creativeAgent)
service.SetBackgroundRemover(newBackgroundRemover(c)) service.SetBackgroundRemover(newBackgroundRemover(c))
service.SetLayeredDocumentGenerator(newLayeredDocumentGenerator(c))
service.SetObjectRecognizer(newObjectRecognizer(c)) service.SetObjectRecognizer(newObjectRecognizer(c))
if mockupAnalyzer, ok := creativeAgent.(design.MockupModelAnalyzer); ok { if mockupAnalyzer, ok := creativeAgent.(design.MockupModelAnalyzer); ok {
service.SetMockupModelAnalyzer(mockupAnalyzer) service.SetMockupModelAnalyzer(mockupAnalyzer)
@@ -317,6 +318,22 @@ func newImageGenerator(c config.Config) piagent.ImageGenerator {
return client return client
} }
func newLayeredDocumentGenerator(c config.Config) design.LayeredDocumentGenerator {
opts := c.Agent.Image
apiKey := resolveImageAPIKey(opts)
client := piagent.NewImageClient(piagent.ImageClientOptions{
BaseURL: opts.BaseURL,
APIKey: apiKey,
InputImageTransport: opts.InputImageTransport,
TimeoutSeconds: opts.TimeoutSeconds,
ResponseHeaderTimeoutSeconds: opts.ResponseHeaderTimeoutSeconds,
})
if client == nil {
return nil
}
return client
}
func newTextExtractor(c config.Config) design.TextExtractor { func newTextExtractor(c config.Config) design.TextExtractor {
opts := c.Agent.Text opts := c.Agent.Text
switch opts.Driver { switch opts.Driver {