feat(piagent): give image generator inline reference placement context

Derive an ordered map of each inline reference image to the surrounding
prompt text describing its role, and feed it into the decision, research,
task-plan, conversation and image-prompt builders. The image prompt now
carries this placement so reference roles are not swapped.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-08 16:17:52 +08:00
parent 9622b27de9
commit 68427ad91a
4 changed files with 339 additions and 2 deletions
@@ -260,6 +260,35 @@ func TestDesignAgentPassesPromptDirectiveReferenceImagesToImageGenerator(t *test
}
}
func TestDesignAgentPreservesInlineReferencePlacementForImageGenerator(t *testing.T) {
imageGenerator := &fakeImageGenerator{}
agent := NewDesignAgent(fakeRunner{}, imageGenerator, fakeCreativeAgent{})
prompt := "参考图 10.jpg):https://example.com/mood.webp 为服装品牌 stillday 创建情绪板 logo 设计 参考图 2image.png):https://example.com/logo.png,包含材质、色彩、摄影姿态。"
_, err := agent.Plan(context.Background(), design.AgentRequest{
Prompt: prompt,
Mode: "image",
ImageModel: "gpt-image-2",
Messages: []design.AgentChatMessage{
{
Role: "user",
Contents: []design.AgentContent{
{Type: "text", Text: prompt, TextSource: "input"},
},
},
},
})
if err != nil {
t.Fatal(err)
}
if len(imageGenerator.opts.Images) != 2 || imageGenerator.opts.Images[0] != "https://example.com/mood.webp" || imageGenerator.opts.Images[1] != "https://example.com/logo.png" {
t.Fatalf("expected ordered reference images, got %#v", imageGenerator.opts.Images)
}
if !containsAll(imageGenerator.prompt, []string{"参考图 2", "image.png", "logo 设计"}) {
t.Fatalf("expected image prompt to carry inline placement semantics, got %s", imageGenerator.prompt)
}
}
func TestDesignAgentUsesDefaultImageSizeWithoutExplicitRequest(t *testing.T) {
imageGenerator := &fakeImageGenerator{}
agent := NewDesignAgent(fakeRunner{}, imageGenerator, fakeCreativeAgent{})