Files
ttstd-infinite-canvas/backend/internal/app/cloud_agent_pi_image_references_test.go
jiabx 10437bdf68 fix(agent): 看图 - 独立运行时的模型步骤带上获准图片清单 (#671)
复现:Agent 调用 canvas_inspect_image 看图后,下一步模型调用报「模型协议引用了未获准的图片」,整轮失败;只要 Agent 看过一次图就必然复现。

原因:看图之后服务端规范历史里会多一条带 resource: 图片占位的 user 消息;旧的 Go 执行循环在发请求前把这些占位对应的资源写进 input.referenceImages,独立 Agent 运行时(Pi)的模型步骤漏了这一步,预检发现占位不在获准清单里就拒绝了请求。

修法:Pi 路径的模型步在组装任务输入前复用同一个 cloudAgentImageReferences 校验与装配(资源归属、大小、图片数量上限),把获准图片清单随请求发出。
2026-10-05 13:28:24 +08:00

45 lines
2.0 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package app
import "testing"
// 复现:canvas_inspect_image 看图后下一次模型调用报「模型协议引用了未获准的图片」。
func TestCloudAgentPiStepImageReferencesSatisfyPlaceholderPreflight(t *testing.T) {
s, _, _ := cloudAgentVisionFixture(t)
state := cloudAgentRuntime{Request: agentTestRequest()}
state.Request.VisionEnabled = true
call := cloudAgentStoryboardCall(t, "canvas_inspect_image", "inspect-cat", map[string]any{"nodeId": "cat"})
result, err := s.prepareCloudAgentImageInspection("user", "agent-canvas", &state, call)
if err != nil {
t.Fatal(err)
}
history := []map[string]any{
{"role": "user", "content": "参考左侧素材"},
{"role": "user", "content": cloudAgentImageContentParts(result.(cloudAgentImageInspection))},
}
// 不带清单时预检拒绝,复现修复前的失败。
bare := canonicalAgentRequest{ToolChoice: "auto", Messages: history}
if err := validateAgentResourcePlaceholders(canvasGenerationInput{Mode: "text", AgentRequests: &agentToolRequests{Canonical: &bare}}); err == nil {
t.Fatal("placeholder without approved references passed preflight")
}
canonical := canonicalAgentRequest{ToolChoice: "auto", Messages: history}
references, err := s.cloudAgentPiStepImageReferences("user", state.Request, &canonical)
if err != nil {
t.Fatal(err)
}
if len(references) != 1 {
t.Fatalf("references = %#v, want the inspected image", references)
}
input := canvasGenerationInput{Mode: "text", ReferenceImages: references, AgentRequests: &agentToolRequests{Canonical: &canonical}}
if err := validateAgentResourcePlaceholders(input); err != nil {
t.Fatalf("preflight still rejects the inspected image: %v", err)
}
// 没有图片的历史不产生清单,也不报错。
plain := canonicalAgentRequest{ToolChoice: "auto", Messages: history[:1]}
if refs, err := s.cloudAgentPiStepImageReferences("user", state.Request, &plain); err != nil || len(refs) != 0 {
t.Fatalf("text-only history: refs=%#v err=%v", refs, err)
}
}