Skip to content

Bug: GoogleAIGeminiChatCompletion doesn't send tools/functions in API request #13400

@hngo1

Description

@hngo1

Describe the bug
When using AddGoogleAIGeminiChatCompletion with FunctionChoiceBehavior or GeminiToolCallBehavior, the connector does not include the tools field in the API request to Gemini. This results in function calling not working at all, even though plugins are correctly registered in the Kernel.
The same configuration works correctly with AddOpenAIChatCompletion using Gemini's OpenAI-compatible endpoint, confirming that the plugin definitions and settings are correct.

To Reproduce

  1. Create a Kernel with AddGoogleAIGeminiChatCompletion
 var kernel = Kernel.CreateBuilder()
    .AddGoogleAIGeminiChatCompletion(
        modelId: "gemini-2.5-flash",
        apiKey: "your-api-key")
    .Build(); 
  1. Register a plugin with [KernelFunction] and [Description] attributes:
public class ProductSearchPlugin
{
    [KernelFunction("search_products")]
    [Description("Search products by keyword")]
    public async Task<string> SearchProducts(
        [Description("Product name or keyword")] string keyword)
    {
        return $"Results for: {keyword}";
    }
}
  1. Create settings with FunctionChoiceBehavior:
var settings = new GeminiPromptExecutionSettings
{
    FunctionChoiceBehavior = FunctionChoiceBehavior.Auto(autoInvoke: false)
};
  1. Call the chat completion:
var chatHistory = new ChatHistory();
chatHistory.AddUserMessage("I want to buy Nike shoes");

var result = await chatCompletionService.GetChatMessageContentAsync(
    chatHistory,
    settings,
    kernel);

var functionCalls = result.Items.OfType<FunctionCallContent>().ToList();
// functionCalls.Count is always 0`
kernel.ImportPluginFromObject(new ProductSearchPlugin(), "ProductSearch");
  1. Enable HTTP logging to inspect the actual request sent to Gemini API.

Expected behavior
The API request to Gemini should include the tools field with function declarations:

{
  "contents": [{"parts":[{"text":"I want to buy Nike shoes"}],"role":"user"}],
  "tools": [{
    "function_declarations": [{
      "name": "search_products",
      "description": "Search products by keyword",
      "parameters": {
        "type": "object",
        "properties": {
          "keyword": {
            "type": "string",
            "description": "Product name or keyword"
          }
        },
        "required": ["keyword"]
      }
    }]
  }],
  "generationConfig": {}
}

Actual behavior
The API request does NOT include the tools field:

{
  "contents": [{"parts":[{"text":"I want to buy Nike shoes"}],"role":"user"}],
  "generationConfig": {}
}

Trace log shows the settings are recognized but not serialized into the request:

trce: Microsoft.SemanticKernel.Connectors.Google.GoogleAIGeminiChatCompletionService[0]
      ChatHistory: [...], Settings: {
        "ToolCallBehavior":null,
        "function_choice_behavior":{"type":"auto","functions":["ProductSearch.search_products"],"options":null}
      }`

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions