Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
fb
  • Loading branch information
christothes committed May 2, 2025
commit fe67356c5c2f90fea8e5a97e5e27773bf309e151
20 changes: 9 additions & 11 deletions src/Utility/ChatTools.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.Reflection;
using System.Text.Json;
using System.Threading.Tasks;
using OpenAI.Agents;
using OpenAI.Chat;
using OpenAI.Embeddings;

Expand Down Expand Up @@ -36,10 +37,10 @@ public ChatTools(EmbeddingClient client = null)
/// <summary>
/// Initializes a new instance of the ChatTools class with the specified tool types.
/// </summary>
/// <param name="additionalTools">Additional tool types to add.</param>
public ChatTools(params Type[] additionalTools) : this((EmbeddingClient)null)
/// <param name="tools">Additional tool types to add.</param>
public ChatTools(params Type[] tools) : this((EmbeddingClient)null)
{
foreach (var t in additionalTools)
foreach (var t in tools)
AddLocalTool(t);
}

Expand Down Expand Up @@ -77,7 +78,7 @@ internal void AddLocalTool(Type tool)
#pragma warning restore IL2070
}

public void AddLocalTool(MethodInfo function)
internal void AddLocalTool(MethodInfo function)
{
string name = function.Name;
var tool = ChatTool.CreateFunctionTool(name, ToolsUtility.GetMethodDescription(function), ToolsUtility.BuildParametersJson(function.GetParameters()));
Expand All @@ -93,7 +94,7 @@ public void AddLocalTool(MethodInfo function)
public async Task AddMcpToolsAsync(McpClient client)
{
if (client == null) throw new ArgumentNullException(nameof(client));
_mcpClientsByEndpoint[client.ServerEndpoint.AbsoluteUri] = client;
_mcpClientsByEndpoint[client.Endpoint.AbsoluteUri] = client;
await client.StartAsync().ConfigureAwait(false);
BinaryData tools = await client.ListToolsAsync().ConfigureAwait(false);
await AddToolsAsync(tools, client).ConfigureAwait(false);
Expand All @@ -105,12 +106,9 @@ public async Task AddMcpToolsAsync(McpClient client)
/// </summary>
/// <param name="mcpEndpoint">The URI endpoint of the MCP server.</param>
/// <returns>A task representing the asynchronous operation.</returns>
public async Task AddMcpToolsAsync(Uri mcpEndpoint) =>
await AddMcpToolsAsync(mcpEndpoint, null).ConfigureAwait(false);

internal async Task AddMcpToolsAsync(Uri serverEndpoint, ClientPipeline pipeline)
public async Task AddMcpToolsAsync(Uri mcpEndpoint)
{
var client = new McpClient(serverEndpoint, pipeline);
var client = new McpClient(mcpEndpoint);
await AddMcpToolsAsync(client).ConfigureAwait(false);
}

Expand All @@ -120,7 +118,7 @@ private async Task AddToolsAsync(BinaryData toolDefinitions, McpClient client)
if (!document.RootElement.TryGetProperty("tools", out JsonElement toolsElement))
throw new JsonException("The JSON document must contain a 'tools' array.");

var serverKey = client.ServerEndpoint.Host + client.ServerEndpoint.Port.ToString();
var serverKey = client.Endpoint.Host + client.Endpoint.Port.ToString();
List<ChatTool> toolsToVectorize = new();

foreach (var tool in toolsElement.EnumerateArray())
Expand Down
11 changes: 5 additions & 6 deletions src/Utility/MCP/McpClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
using System.ClientModel.Primitives;
using System.Threading.Tasks;

namespace OpenAI;
namespace OpenAI.Agents;

/// <summary>
/// Client for interacting with a Model Context Protocol (MCP) server.
Expand All @@ -15,18 +15,17 @@ public class McpClient
/// <summary>
/// Gets the endpoint URI of the MCP server.
/// </summary>
public virtual Uri ServerEndpoint { get; }
public virtual Uri Endpoint { get; }

/// <summary>
/// Initializes a new instance of the <see cref="McpClient"/> class.
/// </summary>
/// <param name="endpoint">The URI endpoint of the MCP server.</param>
/// <param name="pipeline">Optional custom client pipeline. If not provided, a default pipeline will be created.</param>
public McpClient(Uri endpoint, ClientPipeline pipeline = null)
public McpClient(Uri endpoint)
{
_pipeline = pipeline ?? ClientPipeline.Create();
_pipeline = ClientPipeline.Create();
_session = new McpSession(endpoint, _pipeline);
ServerEndpoint = endpoint;
Endpoint = endpoint;
}

/// <summary>
Expand Down
25 changes: 10 additions & 15 deletions src/Utility/ResponseTools.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.Reflection;
using System.Text.Json;
using System.Threading.Tasks;
using OpenAI.Agents;
using OpenAI.Embeddings;
using OpenAI.Responses;

Expand Down Expand Up @@ -36,14 +37,11 @@ public ResponseTools(EmbeddingClient client = null)
/// <summary>
/// Initializes a new instance of the ResponseTools class with the specified tool types.
/// </summary>
/// <param name="tool">The primary tool type to add.</param>
/// <param name="additionalTools">Additional tool types to add.</param>
public ResponseTools(Type tool, params Type[] additionalTools) : this((EmbeddingClient)null)
/// <param name="tools">Additional tool types to add.</param>
public ResponseTools(params Type[] tools) : this((EmbeddingClient)null)
{
AddLocalTool(tool);
if (additionalTools != null)
foreach (var t in additionalTools)
AddLocalTool(t);
foreach (var t in tools)
AddLocalTool(t);
}

/// <summary>
Expand Down Expand Up @@ -80,7 +78,7 @@ internal void AddLocalTool(Type tool)
#pragma warning restore IL2070
}

public void AddLocalTool(MethodInfo function)
internal void AddLocalTool(MethodInfo function)
{
string name = function.Name;
var tool = ResponseTool.CreateFunctionTool(name, ToolsUtility.GetMethodDescription(function), ToolsUtility.BuildParametersJson(function.GetParameters()));
Expand All @@ -96,7 +94,7 @@ public void AddLocalTool(MethodInfo function)
public async Task AddMcpToolsAsync(McpClient client)
{
if (client == null) throw new ArgumentNullException(nameof(client));
_mcpClientsByEndpoint[client.ServerEndpoint.AbsoluteUri] = client;
_mcpClientsByEndpoint[client.Endpoint.AbsoluteUri] = client;
await client.StartAsync().ConfigureAwait(false);
BinaryData tools = await client.ListToolsAsync().ConfigureAwait(false);
await AddToolsAsync(tools, client).ConfigureAwait(false);
Expand All @@ -108,12 +106,9 @@ public async Task AddMcpToolsAsync(McpClient client)
/// </summary>
/// <param name="mcpEndpoint">The URI endpoint of the MCP server.</param>
/// <returns>A task representing the asynchronous operation.</returns>
public async Task AddMcpToolsAsync(Uri mcpEndpoint) =>
await AddMcpToolsAsync(mcpEndpoint, null).ConfigureAwait(false);

internal async Task AddMcpToolsAsync(Uri serverEndpoint, ClientPipeline pipeline)
public async Task AddMcpToolsAsync(Uri mcpEndpoint)
{
var client = new McpClient(serverEndpoint, pipeline);
var client = new McpClient(mcpEndpoint);
await AddMcpToolsAsync(client).ConfigureAwait(false);
}

Expand All @@ -123,7 +118,7 @@ private async Task AddToolsAsync(BinaryData toolDefinitions, McpClient client)
if (!document.RootElement.TryGetProperty("tools", out JsonElement toolsElement))
throw new JsonException("The JSON document must contain a 'tools' array.");

var serverKey = client.ServerEndpoint.Host + client.ServerEndpoint.Port.ToString();
var serverKey = client.Endpoint.Host + client.Endpoint.Port.ToString();
List<ResponseTool> toolsToVectorize = new();

foreach (var tool in toolsElement.EnumerateArray())
Expand Down
9 changes: 5 additions & 4 deletions tests/Utility/ChatToolsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using OpenAI.Agents;

namespace OpenAI.Tests.Utility;

Expand Down Expand Up @@ -134,7 +135,7 @@ public async Task AddMcpToolsAsync_AddsToolsCorrectly()
{
// Arrange
var mcpEndpoint = new Uri("http://localhost:1234");
var mockMcpClient = new Mock<McpClient>(mcpEndpoint, null);
var mockMcpClient = new Mock<McpClient>(mcpEndpoint);
var tools = new ChatTools();

var mockToolsResponse = BinaryData.FromString(@"
Expand Down Expand Up @@ -185,7 +186,7 @@ public async Task AddMcpToolsAsync_AddsToolsCorrectly()
.ReturnsAsync(mockToolsResponse);
mockMcpClient.Setup(c => c.CallToolAsync(It.IsAny<string>(), It.IsAny<BinaryData>()))
.ReturnsAsync(BinaryData.FromString("\"test result\""));
mockMcpClient.SetupGet(c => c.ServerEndpoint)
mockMcpClient.SetupGet(c => c.Endpoint)
.Returns(mcpEndpoint);

// Act
Expand All @@ -212,7 +213,7 @@ public async Task CreateCompletionOptions_WithMaxToolsParameter_FiltersTools()
{
// Arrange
var mcpEndpoint = new Uri("http://localhost:1234");
var mockMcpClient = new Mock<McpClient>(mcpEndpoint, null);
var mockMcpClient = new Mock<McpClient>(mcpEndpoint);
var tools = new ChatTools(mockEmbeddingClient.Object);

var mockToolsResponse = BinaryData.FromString(@"
Expand Down Expand Up @@ -283,7 +284,7 @@ public async Task CreateCompletionOptions_WithMaxToolsParameter_FiltersTools()
.ReturnsAsync(mockToolsResponse);
mockMcpClient.Setup(c => c.CallToolAsync("math-tool", It.IsAny<BinaryData>()))
.ReturnsAsync(BinaryData.FromString("\"math-tool result\""));
mockMcpClient.SetupGet(c => c.ServerEndpoint)
mockMcpClient.SetupGet(c => c.Endpoint)
.Returns(mcpEndpoint);

mockEmbeddingClient
Expand Down
9 changes: 5 additions & 4 deletions tests/Utility/ResponseToolsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using OpenAI.Responses;
using System.ClientModel;
using System.ClientModel.Primitives;
using OpenAI.Agents;

namespace OpenAI.Tests.Utility;

Expand Down Expand Up @@ -138,7 +139,7 @@ public async Task ReturnsErrorForNonExistentTool()
public async Task AddMcpToolsAsync_AddsToolsCorrectly()
{
// Arrange
var mockMcpClient = new Mock<McpClient>(new Uri("http://localhost:1234"), null);
var mockMcpClient = new Mock<McpClient>(new Uri("http://localhost:1234"));
var tools = new ResponseTools();

var mockToolsResponse = BinaryData.FromString(@"
Expand Down Expand Up @@ -189,7 +190,7 @@ public async Task AddMcpToolsAsync_AddsToolsCorrectly()
.ReturnsAsync(mockToolsResponse);
mockMcpClient.Setup(c => c.CallToolAsync(It.IsAny<string>(), It.IsAny<BinaryData>()))
.ReturnsAsync(BinaryData.FromString("\"test result\""));
mockMcpClient.SetupGet(c => c.ServerEndpoint)
mockMcpClient.SetupGet(c => c.Endpoint)
.Returns(new Uri("http://localhost:1234"));

// Act
Expand All @@ -216,7 +217,7 @@ public async Task AddMcpToolsAsync_AddsToolsCorrectly()
public async Task CreateResponseOptions_WithMaxToolsParameter_FiltersTools()
{
// Arrange
var mockMcpClient = new Mock<McpClient>(new Uri("http://localhost:1234"), null);
var mockMcpClient = new Mock<McpClient>(new Uri("http://localhost:1234"));
var tools = new ResponseTools(mockEmbeddingClient.Object);

var mockToolsResponse = BinaryData.FromString(@"
Expand Down Expand Up @@ -287,7 +288,7 @@ public async Task CreateResponseOptions_WithMaxToolsParameter_FiltersTools()
.ReturnsAsync(mockToolsResponse);
mockMcpClient.Setup(c => c.CallToolAsync("math-tool", It.IsAny<BinaryData>()))
.ReturnsAsync(BinaryData.FromString("\"math-tool result\""));
mockMcpClient.SetupGet(c => c.ServerEndpoint)
mockMcpClient.SetupGet(c => c.Endpoint)
.Returns(new Uri("http://localhost:1234"));

mockEmbeddingClient
Expand Down