Skip to content

Commit bf3a238

Browse files
committed
Allow setting Grok options via agent configuration too
Both reasoning effort and search mode. Note that grok-4 does not support reasoning effort: see https://docs.x.ai/docs/guides/reasoning#control-how-hard-the-model-thinks.
1 parent faf6d74 commit bf3a238

File tree

2 files changed

+44
-3
lines changed

2 files changed

+44
-3
lines changed

src/Agents/ConfigurableAIAgent.cs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System.ComponentModel;
22
using System.Text.Json;
33
using Devlooped.Extensions.AI;
4+
using Devlooped.Extensions.AI.Grok;
45
using Microsoft.Agents.AI;
56
using Microsoft.Extensions.AI;
67
using Microsoft.Extensions.Configuration;
@@ -86,9 +87,11 @@ public override IAsyncEnumerable<AgentRunResponseUpdate> RunStreamingAsync(IEnum
8687
?? throw new InvalidOperationException($"A client must be specified for agent '{name}' in configuration section '{section}'."))
8788
?? throw new InvalidOperationException($"Specified chat client '{options?.Client}' for agent '{name}' is not registered.");
8889

89-
#pragma warning disable SYSLIB1100
90-
var chat = configSection.GetSection("options").Get<ExtendedChatOptions>();
91-
#pragma warning restore SYSLIB1100
90+
var provider = client.GetService<ChatClientMetadata>()?.ProviderName;
91+
ChatOptions? chat = provider == "xai"
92+
? configSection.GetSection("options").Get<GrokChatOptions>()
93+
: configSection.GetSection("options").Get<ExtendedChatOptions>();
94+
9295
if (chat is not null)
9396
options.ChatOptions = chat;
9497

src/Tests/ConfigurableAgentTests.cs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using Devlooped.Extensions.AI;
2+
using Devlooped.Extensions.AI.Grok;
23
using Microsoft.Agents.AI;
34
using Microsoft.Extensions.AI;
45
using Microsoft.Extensions.Configuration;
@@ -211,5 +212,42 @@ public void CanSetOpenAIReasoningAndVerbosity()
211212
Assert.Equal(Verbosity.Low, options?.ChatOptions?.Verbosity);
212213
Assert.Equal(ReasoningEffort.Minimal, options?.ChatOptions?.ReasoningEffort);
213214
}
215+
216+
[Fact]
217+
public void CanSetGrokOptions()
218+
{
219+
var builder = new HostApplicationBuilder();
220+
221+
builder.Configuration.AddInMemoryCollection(new Dictionary<string, string?>
222+
{
223+
["ai:clients:grok:modelid"] = "grok-4",
224+
["ai:clients:grok:apikey"] = "xai-asdfasdf",
225+
["ai:clients:grok:endpoint"] = "https://api.x.ai",
226+
["ai:agents:bot:client"] = "grok",
227+
["ai:agents:bot:options:reasoningeffort"] = "low",
228+
["ai:agents:bot:options:search"] = "auto",
229+
});
230+
231+
var app = builder.AddAIAgents().Build();
232+
var agent = app.Services.GetRequiredKeyedService<AIAgent>("bot");
233+
var options = agent.GetService<ChatClientAgentOptions>();
234+
235+
var grok = Assert.IsType<GrokChatOptions>(options?.ChatOptions);
236+
237+
Assert.Equal(ReasoningEffort.Low, grok.ReasoningEffort);
238+
Assert.Equal(GrokSearch.Auto, grok.Search);
239+
240+
var configuration = (IConfigurationRoot)app.Services.GetRequiredService<IConfiguration>();
241+
configuration["ai:agents:bot:options:reasoningeffort"] = "high";
242+
configuration["ai:agents:bot:options:search"] = "off";
243+
// NOTE: the in-memory provider does not support reload on change, so we must trigger it manually.
244+
configuration.Reload();
245+
246+
options = agent.GetService<ChatClientAgentOptions>();
247+
grok = Assert.IsType<GrokChatOptions>(options?.ChatOptions);
248+
249+
Assert.Equal(ReasoningEffort.High, grok.ReasoningEffort);
250+
Assert.Equal(GrokSearch.Off, grok.Search);
251+
}
214252
}
215253

0 commit comments

Comments
 (0)