@@ -688,4 +688,131 @@ void testGenerateContentWithStructuredResponseJsonSchema() {
688688 final UserMessage userMessage = (UserMessage ) capturedRequest .messages ().get (0 );
689689 assertThat (userMessage .singleText ()).isEqualTo ("Give me information about John Doe" );
690690 }
691+
692+ @ Test
693+ @ DisplayName ("Should handle MCP tools with parametersJsonSchema" )
694+ void testGenerateContentWithMcpToolParametersJsonSchema () {
695+ // Given
696+ // Create a mock BaseTool for MCP tool
697+ final com .google .adk .tools .BaseTool mcpTool = mock (com .google .adk .tools .BaseTool .class );
698+ when (mcpTool .name ()).thenReturn ("mcpTool" );
699+ when (mcpTool .description ()).thenReturn ("An MCP tool" );
700+
701+ // Create a mock FunctionDeclaration
702+ final FunctionDeclaration functionDeclaration = mock (FunctionDeclaration .class );
703+ when (mcpTool .declaration ()).thenReturn (Optional .of (functionDeclaration ));
704+
705+ // MCP tools use parametersJsonSchema() instead of parameters()
706+ // Create a JSON schema object (Map representation)
707+ final Map <String , Object > jsonSchemaMap =
708+ Map .of (
709+ "type" ,
710+ "object" ,
711+ "properties" ,
712+ Map .of ("city" , Map .of ("type" , "string" , "description" , "City name" )),
713+ "required" ,
714+ List .of ("city" ));
715+
716+ // Mock parametersJsonSchema() to return the JSON schema object
717+ when (functionDeclaration .parametersJsonSchema ()).thenReturn (Optional .of (jsonSchemaMap ));
718+ when (functionDeclaration .parameters ()).thenReturn (Optional .empty ());
719+
720+ // Create a LlmRequest with the MCP tool
721+ final LlmRequest llmRequest =
722+ LlmRequest .builder ()
723+ .contents (List .of (Content .fromParts (Part .fromText ("Use the MCP tool" ))))
724+ .tools (Map .of ("mcpTool" , mcpTool ))
725+ .build ();
726+
727+ // Mock the AI response
728+ final AiMessage aiMessage = AiMessage .from ("Tool executed successfully" );
729+
730+ final ChatResponse chatResponse = mock (ChatResponse .class );
731+ when (chatResponse .aiMessage ()).thenReturn (aiMessage );
732+ when (chatModel .chat (any (ChatRequest .class ))).thenReturn (chatResponse );
733+
734+ // When
735+ final LlmResponse response = langChain4j .generateContent (llmRequest , false ).blockingFirst ();
736+
737+ // Then
738+ // Verify the response
739+ assertThat (response ).isNotNull ();
740+ assertThat (response .content ()).isPresent ();
741+ assertThat (response .content ().get ().text ()).isEqualTo ("Tool executed successfully" );
742+
743+ // Verify the request was built correctly with the tool specification
744+ final ArgumentCaptor <ChatRequest > requestCaptor = ArgumentCaptor .forClass (ChatRequest .class );
745+ verify (chatModel ).chat (requestCaptor .capture ());
746+ final ChatRequest capturedRequest = requestCaptor .getValue ();
747+
748+ // Verify tool specifications were created from parametersJsonSchema
749+ assertThat (capturedRequest .toolSpecifications ()).isNotEmpty ();
750+ assertThat (capturedRequest .toolSpecifications ().get (0 ).name ()).isEqualTo ("mcpTool" );
751+ assertThat (capturedRequest .toolSpecifications ().get (0 ).description ()).isEqualTo ("An MCP tool" );
752+ }
753+
754+ @ Test
755+ @ DisplayName ("Should handle MCP tools with parametersJsonSchema when it's already a Schema" )
756+ void testGenerateContentWithMcpToolParametersJsonSchemaAsSchema () {
757+ // Given
758+ // Create a mock BaseTool for MCP tool
759+ final com .google .adk .tools .BaseTool mcpTool = mock (com .google .adk .tools .BaseTool .class );
760+ when (mcpTool .name ()).thenReturn ("mcpTool" );
761+ when (mcpTool .description ()).thenReturn ("An MCP tool" );
762+
763+ // Create a mock FunctionDeclaration
764+ final FunctionDeclaration functionDeclaration = mock (FunctionDeclaration .class );
765+ when (mcpTool .declaration ()).thenReturn (Optional .of (functionDeclaration ));
766+
767+ // Create a Schema object directly (when parametersJsonSchema returns Schema)
768+ final Schema cityPropertySchema =
769+ Schema .builder ()
770+ .type (Type .builder ().knownEnum (Type .Known .STRING ).build ())
771+ .description ("City name" )
772+ .build ();
773+
774+ final Schema objectSchema =
775+ Schema .builder ()
776+ .type (Type .builder ().knownEnum (Type .Known .OBJECT ).build ())
777+ .properties (Map .of ("city" , cityPropertySchema ))
778+ .required (List .of ("city" ))
779+ .build ();
780+
781+ // Mock parametersJsonSchema() to return Schema directly
782+ when (functionDeclaration .parametersJsonSchema ()).thenReturn (Optional .of (objectSchema ));
783+ when (functionDeclaration .parameters ()).thenReturn (Optional .empty ());
784+
785+ // Create a LlmRequest with the MCP tool
786+ final LlmRequest llmRequest =
787+ LlmRequest .builder ()
788+ .contents (List .of (Content .fromParts (Part .fromText ("Use the MCP tool" ))))
789+ .tools (Map .of ("mcpTool" , mcpTool ))
790+ .build ();
791+
792+ // Mock the AI response
793+ final AiMessage aiMessage = AiMessage .from ("Tool executed successfully" );
794+
795+ final ChatResponse chatResponse = mock (ChatResponse .class );
796+ when (chatResponse .aiMessage ()).thenReturn (aiMessage );
797+ when (chatModel .chat (any (ChatRequest .class ))).thenReturn (chatResponse );
798+
799+ // When
800+ final LlmResponse response = langChain4j .generateContent (llmRequest , false ).blockingFirst ();
801+
802+ // Then
803+ // Verify the response
804+ assertThat (response ).isNotNull ();
805+ assertThat (response .content ()).isPresent ();
806+ assertThat (response .content ().get ().text ()).isEqualTo ("Tool executed successfully" );
807+
808+ // Verify the request was built correctly with the tool specification
809+ final ArgumentCaptor <ChatRequest > requestCaptor = ArgumentCaptor .forClass (ChatRequest .class );
810+ verify (chatModel ).chat (requestCaptor .capture ());
811+ final ChatRequest capturedRequest = requestCaptor .getValue ();
812+
813+ // Verify tool specifications were created from parametersJsonSchema
814+ assertThat (capturedRequest .toolSpecifications ()).isNotEmpty ();
815+ assertThat (capturedRequest .toolSpecifications ().get (0 ).name ()).isEqualTo ("mcpTool" );
816+ assertThat (capturedRequest .toolSpecifications ().get (0 ).description ()).isEqualTo ("An MCP tool" );
817+ }
691818}
0 commit comments