diff --git a/extensions/copilot/src/platform/endpoint/node/chatEndpoint.ts b/extensions/copilot/src/platform/endpoint/node/chatEndpoint.ts index 7ee7bf18123..a1c499abae0 100644 --- a/extensions/copilot/src/platform/endpoint/node/chatEndpoint.ts +++ b/extensions/copilot/src/platform/endpoint/node/chatEndpoint.ts @@ -316,6 +316,20 @@ export class ChatEndpoint implements IChatEndpoint { body.thinking_budget = thinkingBudget; } } + + // Apply Gemini function calling mode if configured + const hasTools = !!options.requestOptions?.tools?.length; + if (hasTools && this.family.toLowerCase().includes('gemini-3')) { + const geminiFunctionCallingMode = this._configurationService.getExperimentBasedConfig( + ConfigKey.TeamInternal.GeminiFunctionCallingMode, + this._expService + ); + // Only override tool_choice if experiment provides a value and user hasn't specified a function call + if (geminiFunctionCallingMode && typeof body.tool_choice !== 'object') { + body.tool_choice = geminiFunctionCallingMode; + } + } + return body; } diff --git a/extensions/copilot/src/platform/endpoint/node/responsesApi.ts b/extensions/copilot/src/platform/endpoint/node/responsesApi.ts index 512a326b4a8..5d32b8e074b 100644 --- a/extensions/copilot/src/platform/endpoint/node/responsesApi.ts +++ b/extensions/copilot/src/platform/endpoint/node/responsesApi.ts @@ -32,11 +32,6 @@ export function createResponsesRequestBody(accessor: ServicesAccessor, options: const expService = accessor.get(IExperimentationService); const verbosity = getVerbosityForModelSync(endpoint); - const hasTools = !!options.requestOptions?.tools?.length; - const geminiFunctionCallingMode = hasTools && endpoint.family.toLowerCase().includes('gemini-3') - ? configService.getExperimentBasedConfig(ConfigKey.TeamInternal.GeminiFunctionCallingMode, expService) - : undefined; - const body: IEndpointBody = { model, ...rawMessagesToResponseAPI(model, options.messages, !!options.ignoreStatefulMarker), @@ -50,11 +45,9 @@ export function createResponsesRequestBody(accessor: ServicesAccessor, options: // Only a subset of completion post options are supported, and some // are renamed. Handle them manually: max_output_tokens: options.postOptions.max_tokens, - tool_choice: geminiFunctionCallingMode && typeof options.postOptions.tool_choice !== 'object' - ? geminiFunctionCallingMode - : (typeof options.postOptions.tool_choice === 'object' - ? { type: 'function', name: options.postOptions.tool_choice.function.name } - : options.postOptions.tool_choice), + tool_choice: typeof options.postOptions.tool_choice === 'object' + ? { type: 'function', name: options.postOptions.tool_choice.function.name } + : options.postOptions.tool_choice, top_logprobs: options.postOptions.logprobs ? 3 : undefined, store: false, text: verbosity ? { verbosity } : undefined,