Skip to content

Commit 13b4da7

Browse files
committed
Add tests and logic for ToolChoice mapping in Grok
Add unit tests for AsCompletionsRequest to verify ToolChoice behavior with various ChatToolMode values. Update GrokProtocolExtensions to set ToolChoice using a switch expression. Add InternalsVisibleTo for Moq proxy generation. Clean up usings and namespaces.
1 parent a479959 commit 13b4da7

3 files changed

Lines changed: 71 additions & 5 deletions

File tree

src/xAI.Tests/GrokConversionTests.cs

Lines changed: 61 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
1-
using System;
2-
using System.Collections.Generic;
3-
using System.Text;
4-
using Google.Protobuf.WellKnownTypes;
1+
using Google.Protobuf.WellKnownTypes;
52
using Microsoft.Extensions.AI;
3+
using Moq;
64
using OpenAI.Responses;
75
using xAI.Protocol;
86

9-
namespace xAI;
7+
namespace xAI.Tests;
108

119
public class GrokConversionTests
1210
{
@@ -278,4 +276,62 @@ public void AsTool_WithHostedMcpTool()
278276
Assert.Contains(KeyValuePair.Create("x-extra", "bar"), tool.Mcp.ExtraHeaders);
279277
Assert.Contains(KeyValuePair.Create("foo", "baz"), tool.Mcp.ExtraHeaders);
280278
}
279+
280+
static IGrokChatClient CreateClient()
281+
{
282+
var mock = new Mock<IGrokChatClient>();
283+
mock.SetupGet(x => x.DefaultModelId).Returns("grok-4");
284+
mock.SetupGet(x => x.EndUserId).Returns((string?)null);
285+
return mock.Object;
286+
}
287+
288+
[Fact]
289+
public void AsCompletionsRequest_NullToolMode_SetsAutoToolChoice()
290+
{
291+
var request = CreateClient().AsCompletionsRequest([], new ChatOptions { ToolMode = null });
292+
293+
Assert.NotNull(request.ToolChoice);
294+
Assert.True(request.ToolChoice.HasMode);
295+
Assert.Equal(Protocol.ToolMode.Auto, request.ToolChoice.Mode);
296+
}
297+
298+
[Fact]
299+
public void AsCompletionsRequest_AutoToolMode_SetsAutoToolChoice()
300+
{
301+
var request = CreateClient().AsCompletionsRequest([], new ChatOptions { ToolMode = ChatToolMode.Auto });
302+
303+
Assert.NotNull(request.ToolChoice);
304+
Assert.True(request.ToolChoice.HasMode);
305+
Assert.Equal(Protocol.ToolMode.Auto, request.ToolChoice.Mode);
306+
}
307+
308+
[Fact]
309+
public void AsCompletionsRequest_NoneToolMode_SetsNoneToolChoice()
310+
{
311+
var request = CreateClient().AsCompletionsRequest([], new ChatOptions { ToolMode = ChatToolMode.None });
312+
313+
Assert.NotNull(request.ToolChoice);
314+
Assert.True(request.ToolChoice.HasMode);
315+
Assert.Equal(Protocol.ToolMode.None, request.ToolChoice.Mode);
316+
}
317+
318+
[Fact]
319+
public void AsCompletionsRequest_RequireAnyToolMode_SetsRequiredToolChoice()
320+
{
321+
var request = CreateClient().AsCompletionsRequest([], new ChatOptions { ToolMode = ChatToolMode.RequireAny });
322+
323+
Assert.NotNull(request.ToolChoice);
324+
Assert.True(request.ToolChoice.HasMode);
325+
Assert.Equal(Protocol.ToolMode.Required, request.ToolChoice.Mode);
326+
}
327+
328+
[Fact]
329+
public void AsCompletionsRequest_RequireSpecificToolMode_SetsFunctionNameToolChoice()
330+
{
331+
var request = CreateClient().AsCompletionsRequest([], new ChatOptions { ToolMode = ChatToolMode.RequireSpecific("get_weather") });
332+
333+
Assert.NotNull(request.ToolChoice);
334+
Assert.True(request.ToolChoice.HasFunctionName);
335+
Assert.Equal("get_weather", request.ToolChoice.FunctionName);
336+
}
281337
}

src/xAI/GrokProtocolExtensions.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,15 @@ internal static GetCompletionsRequest AsCompletionsRequest(this IGrokChatClient
247247
});
248248
}
249249

250+
request.ToolChoice = options?.ToolMode switch
251+
{
252+
null or AutoChatToolMode => new ToolChoice { Mode = ToolMode.Auto },
253+
NoneChatToolMode => new ToolChoice { Mode = ToolMode.None },
254+
RequiredChatToolMode { RequiredFunctionName: { } name } => new ToolChoice { FunctionName = name },
255+
RequiredChatToolMode => new ToolChoice { Mode = ToolMode.Required },
256+
_ => null
257+
};
258+
250259
foreach (var message in messages)
251260
{
252261
if (message.RawRepresentation is Message input)

src/xAI/xAI.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
<ItemGroup>
2626
<None Include="..\..\osmfeula.txt" Link="osmfeula.txt" PackagePath="OSMFEULA.txt" />
2727
<InternalsVisibleTo Include="xAI.Tests" />
28+
<InternalsVisibleTo Include="DynamicProxyGenAssembly2"/>
2829
</ItemGroup>
2930

3031
<ItemGroup>

0 commit comments

Comments
 (0)