Bug description

https://github.com/spring-projects/spring-ai/blob/1.1.0-M3/models/spring-ai-vertex-ai-gemini/src/main/java/org/springframework/ai/vertexai/gemini/VertexAiGeminiChatModel.java#L608

Multiple parts can be returned, including some with text and some with function calls.

The code currently drops all function calls if a part without function calls exists.

Expected behavior

Both function calls and text should be accumulated into the AssistantMessage

A simple fix (might not be perfect!) I've put in place that I hope to raise a PR for:

List<AssistantMessage.ToolCall> assistantToolCalls = candidate
    .getContent()
    .getPartsList()
    .stream()
    .filter(Part::hasFunctionCall)
    .map(part -> {
        FunctionCall functionCall = part.getFunctionCall();
        var functionName = functionCall.getName();
        String functionArguments = structToJson(functionCall.getArgs());
        return new AssistantMessage.ToolCall("", "function", functionName, functionArguments);
    })
    .toList();

String text = candidate
    .getContent()
    .getPartsList()
    .stream()
    .filter(part -> part.hasText() && !part.getText().isEmpty())
    .map(Part::getText)
    .collect(Collectors.joining(" "));

AssistantMessage assistantMessage = AssistantMessage
    .builder()
    .content(text)
    .properties(messageMetadata)
    .toolCalls(assistantToolCalls)
    .build();