@@ -20,9 +20,13 @@ import (
2020 "testing"
2121 "time"
2222
23+ "google.golang.org/genai"
24+
2325 "google.golang.org/adk/v2/agent"
2426 "google.golang.org/adk/v2/internal/toolinternal"
27+ "google.golang.org/adk/v2/internal/toolinternal/toolutils"
2528 "google.golang.org/adk/v2/memory"
29+ "google.golang.org/adk/v2/model"
2630 "google.golang.org/adk/v2/session"
2731 "google.golang.org/adk/v2/tool"
2832 "google.golang.org/adk/v2/tool/agenttool"
@@ -296,3 +300,121 @@ func TestWithConfirmation(t *testing.T) {
296300 })
297301 }
298302}
303+
304+ type mockCustomRequestTool struct {
305+ tool.Tool
306+ decl * genai.FunctionDeclaration
307+ processRequestCalled * bool
308+ }
309+
310+ func (m * mockCustomRequestTool ) Declaration () * genai.FunctionDeclaration { return m .decl }
311+ func (m * mockCustomRequestTool ) Run (ctx agent.Context , args any ) (map [string ]any , error ) {
312+ return map [string ]any {}, nil
313+ }
314+
315+ func (m * mockCustomRequestTool ) ProcessRequest (ctx agent.Context , req * model.LLMRequest ) error {
316+ * m .processRequestCalled = true
317+ return nil
318+ }
319+
320+ func TestWithConfirmation_ProcessRequest (t * testing.T ) {
321+ processRequestCalled := false
322+ baseTool , err := functiontool .New (functiontool.Config {Name : "customReqTool" }, func (ctx agent.Context , input struct {}) (struct {}, error ) {
323+ return struct {}{}, nil
324+ })
325+ if err != nil {
326+ t .Fatalf ("functiontool.New() failed: %v" , err )
327+ }
328+
329+ customTool := & mockCustomRequestTool {
330+ Tool : baseTool ,
331+ decl : & genai.FunctionDeclaration {Name : "customReqTool" },
332+ processRequestCalled : & processRequestCalled ,
333+ }
334+
335+ ts := & testToolset {tools : []tool.Tool {customTool }}
336+ cts := tool .WithConfirmation (ts , true , nil )
337+
338+ tools , err := cts .Tools (nil )
339+ if err != nil {
340+ t .Fatalf ("cts.Tools() failed: %v" , err )
341+ }
342+ if len (tools ) != 1 {
343+ t .Fatalf ("cts.Tools() returned %d tools, want 1" , len (tools ))
344+ }
345+
346+ processor , ok := tools [0 ].(toolinternal.RequestProcessor )
347+ if ! ok {
348+ t .Fatalf ("wrapped tool does not implement RequestProcessor" )
349+ }
350+
351+ req := & model.LLMRequest {}
352+ if err := processor .ProcessRequest (nil , req ); err != nil {
353+ t .Fatalf ("ProcessRequest() failed: %v" , err )
354+ }
355+
356+ if ! processRequestCalled {
357+ t .Errorf ("expected wrapped tool's ProcessRequest to be called, but it was not" )
358+ }
359+ }
360+
361+ type mockCustomRequestPackingTool struct {
362+ tool.Tool
363+ decl * genai.FunctionDeclaration
364+ processRequestCalled * bool
365+ }
366+
367+ func (m * mockCustomRequestPackingTool ) Declaration () * genai.FunctionDeclaration { return m .decl }
368+ func (m * mockCustomRequestPackingTool ) Run (ctx agent.Context , args any ) (map [string ]any , error ) {
369+ return map [string ]any {}, nil
370+ }
371+
372+ func (m * mockCustomRequestPackingTool ) ProcessRequest (ctx agent.Context , req * model.LLMRequest ) error {
373+ * m .processRequestCalled = true
374+ return toolutils .PackTool (req , m )
375+ }
376+
377+ func TestWithConfirmation_ProcessRequest_Packing (t * testing.T ) {
378+ processRequestCalled := false
379+ baseTool , err := functiontool .New (functiontool.Config {Name : "customPackingTool" }, func (ctx agent.Context , input struct {}) (struct {}, error ) {
380+ return struct {}{}, nil
381+ })
382+ if err != nil {
383+ t .Fatalf ("functiontool.New() failed: %v" , err )
384+ }
385+
386+ customTool := & mockCustomRequestPackingTool {
387+ Tool : baseTool ,
388+ decl : & genai.FunctionDeclaration {Name : "customPackingTool" },
389+ processRequestCalled : & processRequestCalled ,
390+ }
391+
392+ ts := & testToolset {tools : []tool.Tool {customTool }}
393+ cts := tool .WithConfirmation (ts , true , nil )
394+
395+ tools , err := cts .Tools (nil )
396+ if err != nil {
397+ t .Fatalf ("cts.Tools() failed: %v" , err )
398+ }
399+ if len (tools ) != 1 {
400+ t .Fatalf ("cts.Tools() returned %d tools, want 1" , len (tools ))
401+ }
402+
403+ processor , ok := tools [0 ].(toolinternal.RequestProcessor )
404+ if ! ok {
405+ t .Fatalf ("wrapped tool does not implement RequestProcessor" )
406+ }
407+
408+ req := & model.LLMRequest {}
409+ if err := processor .ProcessRequest (nil , req ); err != nil {
410+ t .Fatalf ("ProcessRequest() failed: %v" , err )
411+ }
412+
413+ if ! processRequestCalled {
414+ t .Errorf ("expected wrapped tool's ProcessRequest to be called, but it was not" )
415+ }
416+
417+ if req .Tools ["customPackingTool" ] != tools [0 ] {
418+ t .Errorf ("expected req.Tools[%q] to be the confirmation wrapper %T, got %T" , "customPackingTool" , tools [0 ], req .Tools ["customPackingTool" ])
419+ }
420+ }
0 commit comments