复现:Agent 调用 canvas_inspect_image 看图后,下一步模型调用报「模型协议引用了未获准的图片」,整轮失败;只要 Agent 看过一次图就必然复现。 原因:看图之后服务端规范历史里会多一条带 resource: 图片占位的 user 消息;旧的 Go 执行循环在发请求前把这些占位对应的资源写进 input.referenceImages,独立 Agent 运行时(Pi)的模型步骤漏了这一步,预检发现占位不在获准清单里就拒绝了请求。 修法:Pi 路径的模型步在组装任务输入前复用同一个 cloudAgentImageReferences 校验与装配(资源归属、大小、图片数量上限),把获准图片清单随请求发出。
45 lines
2.0 KiB
Go
45 lines
2.0 KiB
Go
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)
|
||
}
|
||
}
|