Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
178 changes: 122 additions & 56 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -325,104 +325,170 @@ configuration without restarting the application.

## Grok

Full support for Grok [Live Search](https://docs.x.ai/docs/guides/live-search)
and [Reasoning](https://docs.x.ai/docs/guides/reasoning) model options.
Full support for Grok new [agentic tools](https://docs.x.ai/docs/guides/tools/overview):

### Web Search

```csharp
// Sample X.AI client usage with .NET
var messages = new Chat()
{
{ "system", "You are a highly intelligent AI assistant." },
{ "user", "What is 101*3?" },
{ "system", "You are an AI assistant that knows how to search the web." },
{ "user", "What's Tesla stock worth today? Search X and the news for latest info." },
};

var grok = new GrokChatClient(Environment.GetEnvironmentVariable("XAI_API_KEY")!, "grok-3-mini");
var grok = new GrokClient(Environment.GetEnvironmentVariable("XAI_API_KEY")!).AsIChatClient("grok-4.1-fast");

var options = new GrokChatOptions
var options = new ChatOptions
{
ModelId = "grok-4-fast-reasoning", // 👈 can override the model on the client
Temperature = 0.7f,
ReasoningEffort = ReasoningEffort.High, // 👈 or Low
Search = GrokSearch.Auto, // 👈 or On/Off
Tools = [new HostedWebSearchTool()] // 👈 compatible with OpenAI
};

var response = await grok.GetResponseAsync(messages, options);
```

Search can alternatively be configured using a regular `ChatOptions`
and adding the `HostedWebSearchTool` to the tools collection, which
sets the live search mode to `auto` like above:
In addition to basic web search as shown above, Grok supports more
[advanced search](https://docs.x.ai/docs/guides/tools/search-tools) scenarios,
which can be opted-in by using Grok-specific types:

```csharp
var messages = new Chat()
{
{ "system", "You are an AI assistant that knows how to search the web." },
{ "user", "What's Tesla stock worth today? Search X and the news for latest info." },
};
var grok = new GrokChatClient(Environment.GetEnvironmentVariable("XAI_API_KEY")!).AsIChatClient("grok-4.1-fast");
var response = await grok.GetResponseAsync(
"What are the latest product news by Tesla?",
new ChatOptions
{
Tools = [new GrokSearchTool()
{
AllowedDomains = [ "ir.tesla.com" ]
}]
});
```

var grok = new GrokChatClient(Environment.GetEnvironmentVariable("XAI_API_KEY")!, "grok-3");
You can alternatively set `ExcludedDomains` instead, and enable image
understanding with `EnableImageUndestanding`. Learn more about these filters
at [web search parameters](https://docs.x.ai/docs/guides/tools/search-tools#web-search-parameters).

var options = new ChatOptions
### X Search

In addition to web search, Grok also supports searching on X (formerly Twitter):

```csharp
var response = await grok.GetResponseAsync(
"What's the latest on Optimus?",
new ChatOptions
{
Tools = [new GrokXSearchTool
{
// AllowedHandles = [...],
// ExcludedHandles = [...],
// EnableImageUnderstanding = true,
// EnableVideoUnderstanding = true,
// FromDate = ...,
// ToDate = ...,
}]
});
```

Learn more about available filters at [X search parameters](https://docs.x.ai/docs/guides/tools/search-tools#x-search-parameters).

You can combine both web and X search in the same request by adding both tools.

### Code Execution

The code execution tool enables Grok to write and execute Python code in real-time,
dramatically expanding its capabilities beyond text generation. This powerful feature
allows Grok to perform precise calculations, complex data analysis, statistical
computations, and solve mathematical problems that would be impossible through text alone.

This is Grok's equivalent of the OpenAI code interpreter, and is configured the same way:

```csharp
var grok = new GrokClient(Configuration["XAI_API_KEY"]!).AsIChatClient("grok-4-fast");
var response = await grok.GetResponseAsync(
"Calculate the compound interest for $10,000 at 5% annually for 10 years",
new ChatOptions
{
Tools = [new HostedCodeInterpreterTool()]
});

var text = response.Text;
Assert.Contains("$6,288.95", text);
```

If you want to access the output from the code execution, you can add that as an
include in the options:

```csharp
var grok = new GrokClient(Configuration["XAI_API_KEY"]!).AsIChatClient("grok-4-fast");
var options = new GrokChatOptions
{
Tools = [new HostedWebSearchTool()] // 👈 equals setting GrokSearch.Auto
Include = { IncludeOption.CodeExecutionCallOutput },
Tools = [new HostedCodeInterpreterTool()]
};

var response = await grok.GetResponseAsync(messages, options);
var response = await grok.GetResponseAsync(
"Calculate the compound interest for $10,000 at 5% annually for 10 years",
options);

var content = response.Messages
.SelectMany(x => x.Contents)
.OfType<CodeInterpreterToolResultContent>()
.First();

foreach (AIContent output in content.Outputs)
// process outputs from code interpreter
```

We also provide an OpenAI-compatible `WebSearchTool` that can be used to restrict
the search to a specific country in a way that works with both Grok and OpenAI:
Learn more about the [code execution tool](https://docs.x.ai/docs/guides/tools/code-execution-tool).

### Collection Search

If you maintain a [collection](https://docs.x.ai/docs/key-information/collections),
Grok can perform semantic search on it:

```csharp
var options = new ChatOptions
{
Tools = [new WebSearchTool("AR")] // 👈 search in Argentina
Tools = [new HostedFileSearchTool {
Inputs = [new HostedVectorStoreContent("[collection_id]")]
}]
};
```

This is equivalent to the following when used with a Grok client:
Learn more about [collection search](https://docs.x.ai/docs/guides/tools/collections-search-tool).

### Remote MCP

Remote MCP Tools allow Grok to connect to external MCP (Model Context Protocol) servers.
This example sets up the GitHub MCP server so queries about releases (limited specifically
in this case):

```csharp
var options = new ChatOptions
{
// 👇 search in Argentina
Tools = [new GrokSearchTool(GrokSearch.On) { Country = "AR" }]
Tools = [new HostedMcpServerTool("GitHub", "https://api.githubcopilot.com/mcp/") {
AuthorizationToken = Configuration["GITHUB_TOKEN"]!,
AllowedTools = ["list_releases"],
}]
};
```

### Advanced Live Search

To configure advanced live search options, beyond the `On|Auto|Off` settings
in `GrokChatOptions`, you can use the `GrokSearchTool` instead, which exposes
the full breath of [live search options](https://docs.x.ai/docs/guides/live-search)
available in the Grok API.
Just like with code execution, you can opt-in to surfacing the MCP outputs in
the response:

```csharp
var options = new ChatOptions
var options = new GrokChatOptions
{
Tools = [new GrokSearchTool(GrokSearch.On)
{
FromDate = new DateOnly(2025, 1, 1),
ToDate = DateOnly.FromDateTime(DateTime.Now),
MaxSearchResults = 10,
Sources =
[
new GrokWebSource
{
AllowedWebsites =
[
"https://catedralaltapatagonia.com",
"https://catedralaltapatagonia.com/parte-de-nieve/",
"https://catedralaltapatagonia.com/tarifas/"
]
},
]
// Exposes McpServerToolResultContent in responses
Include = { IncludeOption.McpCallOutput },
Tools = [new HostedMcpServerTool("GitHub", "https://api.githubcopilot.com/mcp/") {
AuthorizationToken = Configuration["GITHUB_TOKEN"]!,
AllowedTools = ["list_releases"],
}]
};

```

> [!TIP]
> You can configure multiple sources including `GrokWebSource`, `GrokNewsSource`,
> `GrokRssSource` and `GrokXSource`, each containing granular options.
Learn more about [Remote MCP tools](https://docs.x.ai/docs/guides/tools/remote-mcp-tools).

## OpenAI

Expand Down
21 changes: 9 additions & 12 deletions src/Tests/GrokTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -251,26 +251,23 @@ public async Task GrokInvokesGrokSearchToolExcludesDomain()
[SecretsFact("XAI_API_KEY")]
public async Task GrokInvokesHostedCodeExecution()
{
var messages = new Chat()
{
{ "user", "Calculate the compound interest for $10,000 at 5% annually for 10 years" },
};

var grok = new GrokClient(Configuration["XAI_API_KEY"]!).AsIChatClient("grok-4-fast");

var options = new ChatOptions
{
Tools = [new HostedCodeInterpreterTool()]
};
var response = await grok.GetResponseAsync(
"Calculate the compound interest for $10,000 at 5% annually for 10 years",
new ChatOptions
{
Tools = [new HostedCodeInterpreterTool()]
});

var response = await grok.GetResponseAsync(messages, options);
var text = response.Text;

Assert.Contains("$6,288.95", text);
Assert.NotEmpty(response.Messages
.SelectMany(x => x.Contents)
.OfType<CodeInterpreterToolCallContent>());

// result content is not available by default
Assert.Empty(response.Messages
.SelectMany(x => x.Contents)
.OfType<CodeInterpreterToolResultContent>());
Expand All @@ -293,13 +290,13 @@ public async Task GrokInvokesHostedCodeExecutionWithOutput()
};

var response = await grok.GetResponseAsync(messages, options);
var text = response.Text;

Assert.Contains("$6,288.95", text);
Assert.Contains("$6,288.95", response.Text);
Assert.NotEmpty(response.Messages
.SelectMany(x => x.Contents)
.OfType<CodeInterpreterToolCallContent>());

// result content opted-in is found
Assert.NotEmpty(response.Messages
.SelectMany(x => x.Contents)
.OfType<CodeInterpreterToolResultContent>());
Expand Down
Loading