Skip to content

Call Gemini function even when text part is returned #3512

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

vlad-stoian
Copy link

Closes gh-2499

Sometimes the model returns a mix of text and function call parts:

content {
  role: "model"
  parts {
    text: "I will use the `get_current_weather` to get the current weather in San Francisco, Paris and Tokyo. I will set the unit to Celsius. Then I will print the temperature for each city.\n"
  }
  parts {
    function_call {
      name: "get_current_weather"
      args {
        fields {
          key: "location"
          value {
            string_value: "San Francisco, CA"
          }
        }
        fields {
          key: "unit"
          value {
            string_value: "C"
          }
        }
      }
    }
  }
  parts {
    function_call {
      name: "get_current_weather"
      args {
        fields {
          key: "location"
          value {
            string_value: "Paris, France"
          }
        }
        fields {
          key: "unit"
          value {
            string_value: "C"
          }
        }
      }
    }
  }
  parts {
    function_call {
      name: "get_current_weather"
      args {
        fields {
          key: "location"
          value {
            string_value: "Tokyo, Japan"
          }
        }
        fields {
          key: "unit"
          value {
            string_value: "C"
          }
        }
      }
    }
  }
}
finish_reason: STOP
avg_logprobs: -0.07267227420559177

An alternative implementation that I was thinking about was along the lines of:

		return candidate.getContent()
			.getPartsList()
			.stream()
			.filter(part -> part.hasText() || part.hasFunctionCall())
			.map(part -> {
				if (part.hasFunctionCall()) {
					FunctionCall functionCall = part.getFunctionCall();
					var functionName = functionCall.getName();
					var functionArguments = structToJson(functionCall.getArgs());
					var assistantToolCalls = List
						.of(new AssistantMessage.ToolCall("", "function", functionName, functionArguments));
					return new AssistantMessage("", messageMetadata, assistantToolCalls);
				}
				return new AssistantMessage(part.getText(), messageMetadata);
			})
			.map(message -> new Generation(message, chatGenerationMetadata))
			.toList();

But with the implementation above, only the first tool will be invoked, and then additional back and forth will happen between Spring AI and Gemini.

Please let me know if I there's anything I could improve.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Gemini and function calling: function call may be discarded.
1 participant