Skip to content
Open
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
2 changes: 1 addition & 1 deletion src/ModelContextProtocol.Core/AIContentExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -434,7 +434,7 @@ public static ContentBlock ToContentBlock(this AIContent content, JsonSerializer
Content =
resultContent.Result is AIContent c ? [c.ToContentBlock(options)] :
resultContent.Result is IEnumerable<AIContent> ec ? [.. ec.Select(c => c.ToContentBlock(options))] :
[new TextContentBlock { Text = JsonSerializer.Serialize(content, options.GetTypeInfo<object>()) }],
[new TextContentBlock { Text = JsonSerializer.Serialize(resultContent.Result, options.GetTypeInfo(typeof(object))) }],
StructuredContent = resultContent.Result is JsonElement je ? je : null,
},

Expand Down
37 changes: 37 additions & 0 deletions tests/ModelContextProtocol.Tests/AIContentExtensionsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,43 @@ public void ToAIContent_ToolResultToFunctionResultRoundTrip()
Assert.NotNull(functionResult.Result);
}

[Fact]
public void ToContentBlock_FunctionResultWithStringResult_TextIsTheResult()
{
FunctionResultContent functionResult = new("call_123", "Weather in Paris: sunny");

var toolResult = Assert.IsType<ToolResultContentBlock>(functionResult.ToContentBlock());

Assert.Equal("call_123", toolResult.ToolUseId);
var text = Assert.IsType<TextContentBlock>(Assert.Single(toolResult.Content));
Assert.Equal("\"Weather in Paris: sunny\"", text.Text);
}

[Fact]
public void ToContentBlock_FunctionResultWithJsonElementResult_TextIsTheResult()
{
JsonElement value = JsonSerializer.SerializeToElement(new Dictionary<string, object?> { ["temperature"] = 22 }, McpJsonUtilities.DefaultOptions);
FunctionResultContent functionResult = new("call_123", value);

var toolResult = Assert.IsType<ToolResultContentBlock>(functionResult.ToContentBlock());

var text = Assert.IsType<TextContentBlock>(Assert.Single(toolResult.Content));
Assert.Equal("""{"temperature":22}""", text.Text);
Assert.NotNull(toolResult.StructuredContent);
Assert.Equal(22, toolResult.StructuredContent.Value.GetProperty("temperature").GetInt32());
}

[Fact]
public void ToContentBlock_FunctionResultWithAIContentResult_ConvertsTheContent()
{
FunctionResultContent functionResult = new("call_123", new TextContent("Weather in Paris: sunny"));

var toolResult = Assert.IsType<ToolResultContentBlock>(functionResult.ToContentBlock());

var text = Assert.IsType<TextContentBlock>(Assert.Single(toolResult.Content));
Assert.Equal("Weather in Paris: sunny", text.Text);
}

// Tests for anonymous types in AdditionalProperties (sampling pipeline regression fix)
// These tests require reflection-based serialization and will be skipped when reflection is disabled.

Expand Down
1 change: 1 addition & 0 deletions tests/ModelContextProtocol.Tests/Client/McpClientTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -653,6 +653,7 @@ public async Task EndToEnd_SamplingWithTools_ServerUsesIChatClientWithFunctionIn

string resultText = toolResult.Result?.ToString() ?? string.Empty;
Assert.Contains("Weather in Paris: sunny", resultText);
Assert.DoesNotContain("callId", resultText);

return Task.FromResult<ChatResponse>(new([
new ChatMessage(ChatRole.User, messages.First().Contents),
Expand Down
Loading