@@ -584,6 +584,9 @@ func TestToolConfirmation(t *testing.T) {
584584 args : map [string ]any {"Num" : 1 },
585585 want : []* genai.Content {
586586 genai .NewContentFromFunctionCall ("test_tool" , map [string ]any {"Num" : 1 }, "model" ),
587+ genai .NewContentFromFunctionResponse ("test_tool" , map [string ]any {
588+ "error" : errors .New ("error tool \" test_tool\" requires confirmation, please approve or reject" ),
589+ }, "user" ),
587590 genai .NewContentFromFunctionCall (toolconfirmation .FunctionCallName , map [string ]any {
588591 "originalFunctionCall" : & genai.FunctionCall {
589592 Args : map [string ]any {"Num" : 1 },
@@ -593,9 +596,6 @@ func TestToolConfirmation(t *testing.T) {
593596 Hint : "Please approve or reject the tool call test_tool() by responding with a FunctionResponse with an expected ToolConfirmation payload." ,
594597 },
595598 }, "model" ),
596- genai .NewContentFromFunctionResponse ("test_tool" , map [string ]any {
597- "error" : errors .New ("error tool \" test_tool\" requires confirmation, please approve or reject" ),
598- }, "user" ),
599599 },
600600 },
601601 {
@@ -608,6 +608,9 @@ func TestToolConfirmation(t *testing.T) {
608608 confirmFunctionResponse : & genai.FunctionResponse {Name : toolconfirmation .FunctionCallName , Response : map [string ]any {"confirmed" : true }},
609609 want : []* genai.Content {
610610 genai .NewContentFromFunctionCall ("test_tool" , map [string ]any {"Num" : 1 }, "model" ),
611+ genai .NewContentFromFunctionResponse ("test_tool" , map [string ]any {
612+ "error" : errors .New ("error tool \" test_tool\" requires confirmation, please approve or reject" ),
613+ }, "user" ),
611614 genai .NewContentFromFunctionCall (toolconfirmation .FunctionCallName , map [string ]any {
612615 "originalFunctionCall" : & genai.FunctionCall {
613616 Args : map [string ]any {"Num" : 1 },
@@ -617,9 +620,6 @@ func TestToolConfirmation(t *testing.T) {
617620 Hint : "Please approve or reject the tool call test_tool() by responding with a FunctionResponse with an expected ToolConfirmation payload." ,
618621 },
619622 }, "model" ),
620- genai .NewContentFromFunctionResponse ("test_tool" , map [string ]any {
621- "error" : errors .New ("error tool \" test_tool\" requires confirmation, please approve or reject" ),
622- }, "user" ),
623623 genai .NewContentFromFunctionResponse ("test_tool" , map [string ]any {"result" : "ok" }, "user" ),
624624 },
625625 },
@@ -633,6 +633,9 @@ func TestToolConfirmation(t *testing.T) {
633633 confirmFunctionResponse : & genai.FunctionResponse {Name : toolconfirmation .FunctionCallName , Response : map [string ]any {"confirmed" : false }},
634634 want : []* genai.Content {
635635 genai .NewContentFromFunctionCall ("test_tool" , map [string ]any {"Num" : 1 }, "model" ),
636+ genai .NewContentFromFunctionResponse ("test_tool" , map [string ]any {
637+ "error" : errors .New ("error tool \" test_tool\" requires confirmation, please approve or reject" ),
638+ }, "user" ),
636639 genai .NewContentFromFunctionCall (toolconfirmation .FunctionCallName , map [string ]any {
637640 "originalFunctionCall" : & genai.FunctionCall {
638641 Args : map [string ]any {"Num" : 1 },
@@ -642,9 +645,6 @@ func TestToolConfirmation(t *testing.T) {
642645 Hint : "Please approve or reject the tool call test_tool() by responding with a FunctionResponse with an expected ToolConfirmation payload." ,
643646 },
644647 }, "model" ),
645- genai .NewContentFromFunctionResponse ("test_tool" , map [string ]any {
646- "error" : errors .New ("error tool \" test_tool\" requires confirmation, please approve or reject" ),
647- }, "user" ),
648648 genai .NewContentFromFunctionResponse ("test_tool" , map [string ]any {
649649 "error" : errors .New ("error tool \" test_tool\" call is rejected" ),
650650 }, "user" ),
@@ -675,6 +675,9 @@ func TestToolConfirmation(t *testing.T) {
675675 args : map [string ]any {"Num" : 4 },
676676 want : []* genai.Content {
677677 genai .NewContentFromFunctionCall ("test_tool" , map [string ]any {"Num" : 4 }, "model" ),
678+ genai .NewContentFromFunctionResponse ("test_tool" , map [string ]any {
679+ "error" : errors .New ("error tool \" test_tool\" requires confirmation, please approve or reject" ),
680+ }, "user" ),
678681 genai .NewContentFromFunctionCall (toolconfirmation .FunctionCallName , map [string ]any {
679682 "originalFunctionCall" : & genai.FunctionCall {
680683 Args : map [string ]any {"Num" : 4 },
@@ -684,9 +687,6 @@ func TestToolConfirmation(t *testing.T) {
684687 Hint : "Please approve or reject the tool call test_tool() by responding with a FunctionResponse with an expected ToolConfirmation payload." ,
685688 },
686689 }, "model" ),
687- genai .NewContentFromFunctionResponse ("test_tool" , map [string ]any {
688- "error" : errors .New ("error tool \" test_tool\" requires confirmation, please approve or reject" ),
689- }, "user" ),
690690 },
691691 },
692692 {
@@ -701,6 +701,9 @@ func TestToolConfirmation(t *testing.T) {
701701 confirmFunctionResponse : & genai.FunctionResponse {Name : toolconfirmation .FunctionCallName , Response : map [string ]any {"confirmed" : true }},
702702 want : []* genai.Content {
703703 genai .NewContentFromFunctionCall ("test_tool" , map [string ]any {"Num" : 4 }, "model" ),
704+ genai .NewContentFromFunctionResponse ("test_tool" , map [string ]any {
705+ "error" : errors .New ("error tool \" test_tool\" requires confirmation, please approve or reject" ),
706+ }, "user" ),
704707 genai .NewContentFromFunctionCall (toolconfirmation .FunctionCallName , map [string ]any {
705708 "originalFunctionCall" : & genai.FunctionCall {
706709 Args : map [string ]any {"Num" : 4 },
@@ -710,9 +713,6 @@ func TestToolConfirmation(t *testing.T) {
710713 Hint : "Please approve or reject the tool call test_tool() by responding with a FunctionResponse with an expected ToolConfirmation payload." ,
711714 },
712715 }, "model" ),
713- genai .NewContentFromFunctionResponse ("test_tool" , map [string ]any {
714- "error" : errors .New ("error tool \" test_tool\" requires confirmation, please approve or reject" ),
715- }, "user" ),
716716 genai .NewContentFromFunctionResponse ("test_tool" , map [string ]any {"result" : "ok" }, "user" ),
717717 },
718718 },
@@ -728,6 +728,9 @@ func TestToolConfirmation(t *testing.T) {
728728 confirmFunctionResponse : & genai.FunctionResponse {Name : toolconfirmation .FunctionCallName , Response : map [string ]any {"confirmed" : false }},
729729 want : []* genai.Content {
730730 genai .NewContentFromFunctionCall ("test_tool" , map [string ]any {"Num" : 4 }, "model" ),
731+ genai .NewContentFromFunctionResponse ("test_tool" , map [string ]any {
732+ "error" : errors .New ("error tool \" test_tool\" requires confirmation, please approve or reject" ),
733+ }, "user" ),
731734 genai .NewContentFromFunctionCall (toolconfirmation .FunctionCallName , map [string ]any {
732735 "originalFunctionCall" : & genai.FunctionCall {
733736 Args : map [string ]any {"Num" : 4 },
@@ -737,9 +740,6 @@ func TestToolConfirmation(t *testing.T) {
737740 Hint : "Please approve or reject the tool call test_tool() by responding with a FunctionResponse with an expected ToolConfirmation payload." ,
738741 },
739742 }, "model" ),
740- genai .NewContentFromFunctionResponse ("test_tool" , map [string ]any {
741- "error" : errors .New ("error tool \" test_tool\" requires confirmation, please approve or reject" ),
742- }, "user" ),
743743 genai .NewContentFromFunctionResponse ("test_tool" , map [string ]any {
744744 "error" : errors .New ("error tool \" test_tool\" call is rejected" ),
745745 }, "user" ),
@@ -865,6 +865,60 @@ func TestToolConfirmation(t *testing.T) {
865865 }
866866}
867867
868+ func TestToolConfirmationYieldsFunctionResponseBeforeConfirmation (t * testing.T ) {
869+ mockModel := & testutil.MockModel {
870+ Responses : []* genai.Content {
871+ genai .NewContentFromFunctionCall ("test_tool" , map [string ]any {"Num" : 1 }, genai .RoleModel ),
872+ },
873+ }
874+
875+ myTool , err := functiontool .New (functiontool.Config {
876+ Name : "test_tool" ,
877+ RequireConfirmation : true ,
878+ }, okFunc )
879+ if err != nil {
880+ t .Fatalf ("Failed to create tool: %v" , err )
881+ }
882+
883+ a , err := llmagent .New (llmagent.Config {
884+ Name : "simple agent" ,
885+ Model : mockModel ,
886+ Tools : []tool.Tool {myTool },
887+ })
888+ if err != nil {
889+ t .Fatalf ("failed to create llm agent: %v" , err )
890+ }
891+
892+ runner := testutil .NewTestAgentRunner (t , a )
893+ sawFunctionResponse := false
894+ sawConfirmation := false
895+
896+ for got , err := range runner .Run (t , "id" , "message" ) {
897+ // The mock model emits a sentinel error once exhausted; treat any
898+ // error as end-of-stream and rely on the post-loop assertions.
899+ if err != nil {
900+ break
901+ }
902+
903+ for _ , part := range got .Content .Parts {
904+ if part .FunctionResponse != nil && part .FunctionResponse .Name == "test_tool" {
905+ sawFunctionResponse = true
906+ }
907+ if part .FunctionCall != nil && part .FunctionCall .Name == toolconfirmation .FunctionCallName {
908+ sawConfirmation = true
909+ if ! sawFunctionResponse {
910+ t .Fatal ("confirmation was yielded before the tool function response" )
911+ }
912+ return
913+ }
914+ }
915+ }
916+
917+ if ! sawConfirmation {
918+ t .Fatal ("expected confirmation event" )
919+ }
920+ }
921+
868922// Mock types for TArgs and TResults
869923type TestArgs struct {
870924 Name string
0 commit comments