feat(piagent): bypass planner for direct image generation modes
For image / pure-image / image-generator / image-action modes, skip the task-planning round trip and hand the prompt straight to the image model, deriving the requested image count from the composer settings. Also normalize completed image-generator nodes back into regular image nodes (clearing the image-generator layer role and defaulting Tone to "visual") when merging generated results and when restoring finished nodes, so a finished generator node is not re-appended as a duplicate. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -50,6 +50,44 @@ func TestMergeGeneratedNodesIntoImageGeneratorTargetUsesGeneratedSizeAndKeepsCen
|
||||
}
|
||||
}
|
||||
|
||||
func TestMergeGeneratedNodesIntoCompletedImageGeneratorTargetDoesNotReappend(t *testing.T) {
|
||||
nodes := []design.Node{
|
||||
{
|
||||
ID: "generator-1",
|
||||
Type: design.NodeTypeImage,
|
||||
Title: "旧图",
|
||||
Content: "https://example.com/old.png",
|
||||
Tone: "visual",
|
||||
Status: "success",
|
||||
LayerRole: "",
|
||||
Width: 360,
|
||||
Height: 240,
|
||||
},
|
||||
}
|
||||
generated := []design.Node{
|
||||
{
|
||||
ID: "generator-1",
|
||||
Type: design.NodeTypeImage,
|
||||
Title: "新图",
|
||||
Content: "https://example.com/new.png",
|
||||
Tone: "image-generator",
|
||||
Status: "success",
|
||||
LayerRole: "image-generator",
|
||||
Width: 1024,
|
||||
Height: 1024,
|
||||
},
|
||||
}
|
||||
|
||||
merged := mergeGeneratedNodesIntoTarget(nodes, generated, "generator-1")
|
||||
if len(merged) != 1 {
|
||||
t.Fatalf("expected existing target to be updated in place, got %#v", merged)
|
||||
}
|
||||
node := merged[0]
|
||||
if node.Content != "https://example.com/new.png" || node.LayerRole != "" || node.Tone != "visual" {
|
||||
t.Fatalf("expected completed image generator to become regular image, got %#v", node)
|
||||
}
|
||||
}
|
||||
|
||||
func TestImageGeneratorTargetNodeIDParsesDirectiveCaseInsensitively(t *testing.T) {
|
||||
targetID := imageGeneratorTargetNodeID([]design.AgentChatMessage{
|
||||
{
|
||||
@@ -64,6 +102,36 @@ func TestImageGeneratorTargetNodeIDParsesDirectiveCaseInsensitively(t *testing.T
|
||||
}
|
||||
}
|
||||
|
||||
func TestRestoreFinishedGeneratedImageNodesConvertsCompletedImageGeneratorNode(t *testing.T) {
|
||||
now := time.Now()
|
||||
project := design.Project{
|
||||
ID: "project-completed-generator",
|
||||
Status: design.StatusReady,
|
||||
Nodes: []design.Node{
|
||||
{
|
||||
ID: "generator-1",
|
||||
Type: design.NodeTypeImage,
|
||||
Title: "生成图片",
|
||||
Content: "http://localhost:19000/canvas-assets/cat.png",
|
||||
Tone: "image-generator",
|
||||
Status: "success",
|
||||
LayerRole: "image-generator",
|
||||
Width: 1024,
|
||||
Height: 1024,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
restored, changed := (*DesignService)(nil).restoreFinishedGeneratedImageNodes(project, now.Add(time.Second))
|
||||
if !changed {
|
||||
t.Fatal("expected completed image generator node to be normalized")
|
||||
}
|
||||
node := restored.Nodes[0]
|
||||
if node.LayerRole != "" || node.Tone != "visual" || node.Status != "success" || node.Content != "http://localhost:19000/canvas-assets/cat.png" {
|
||||
t.Fatalf("expected regular completed image node, got %#v", node)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRestoreFinishedGeneratedImageNodesRepairsStaleCanvasSnapshot(t *testing.T) {
|
||||
now := time.Now()
|
||||
project := design.Project{
|
||||
|
||||
Reference in New Issue
Block a user