Skip to content

Commit 10534c5

Browse files
authored
Fixes for MCPSession (Azure#49106)
1 parent e7a3129 commit 10534c5

File tree

2 files changed

+16
-8
lines changed

2 files changed

+16
-8
lines changed

sdk/cloudmachine/Azure.Projects.OpenAI/src/ChatTools.cs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ public class ChatTools
2424

2525
private List<McpClient> _mcpClients = [];
2626
private Dictionary<string, McpClient> _mcpClientsByEndpoint = [];
27+
private const string _mcpToolSeparator = "_._";
2728

2829
/// <summary>
2930
/// Initializes a new instance of the <see cref="ChatTools"/> class.
@@ -85,13 +86,18 @@ internal void Add(BinaryData toolDefinitions, McpClient client)
8586

8687
var tools = toolsElement.EnumerateArray();
8788
// the replacement is to deal with OpenAI's tool name regex validation.
88-
var serverKey = client.ServerEndpoint.AbsoluteUri.Replace('/', '_').Replace(':', '_');
89+
var serverKey = client.ServerEndpoint.Host + client.ServerEndpoint.Port.ToString();
8990

9091
foreach (var tool in tools)
9192
{
92-
var name = $"{serverKey}__.__{tool.GetProperty("name").GetString()!}";
93+
var name = $"{serverKey}{_mcpToolSeparator}{tool.GetProperty("name").GetString()!}";
9394
var description = tool.GetProperty("description").GetString()!;
94-
var inputSchema = tool.GetProperty("inputSchema").GetRawText();
95+
var inputSchema = JsonSerializer.Serialize(
96+
JsonSerializer.Deserialize<JsonElement>(tool.GetProperty("inputSchema").GetRawText()),
97+
new JsonSerializerOptions
98+
{
99+
Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
100+
});
95101

96102
var chatTool = ChatTool.CreateFunctionTool(
97103
name,
@@ -188,11 +194,10 @@ private async Task<string> CallMcp(ChatToolCall call)
188194
if (_mcpMethods.TryGetValue(call.FunctionName, out Func<string, BinaryData, Task<BinaryData>>? method))
189195
{
190196
#if !NETSTANDARD2_0
191-
var actualFunctionName = call.FunctionName.Split("__.__", 2)[1];
197+
var actualFunctionName = call.FunctionName.Split(_mcpToolSeparator, 2)[1];
192198
#else
193-
var separator = "__.__";
194-
var index = call.FunctionName.IndexOf(separator);
195-
var actualFunctionName = call.FunctionName.Substring(index + separator.Length);
199+
var index = call.FunctionName.IndexOf(_mcpToolSeparator);
200+
var actualFunctionName = call.FunctionName.Substring(index + _mcpToolSeparator.Length);
196201
#endif
197202
var result = await method(actualFunctionName, call.FunctionArguments).ConfigureAwait(false);
198203
return result.ToString();

sdk/cloudmachine/Azure.Projects.OpenAI/src/McpSession.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,8 @@ private async Task ProcessSseStreamAsync(StreamReader streamReader)
134134
throw new IOException("SSE stream closed unexpectedly");
135135
}
136136

137+
DebugPrint($"Received line: '{line}'");
138+
137139
if (line.StartsWith("event:", StringComparison.OrdinalIgnoreCase))
138140
{
139141
eventName = line.AsSpan(6).Trim().ToString();
@@ -181,6 +183,7 @@ private async Task ProcessEventAsync(SseEvent sseEvent)
181183
break;
182184

183185
case "message":
186+
case "": // Handle empty event name as a message
184187
DebugPrint($"Received message: {sseEvent.Data}");
185188
await _messageRouter.RouteMessageAsync(sseEvent).ConfigureAwait(false);
186189
break;
@@ -429,7 +432,7 @@ public void RegisterHandler(int id, Func<SseEvent, Task> handler)
429432
// Route a message to its registered handler
430433
public async Task RouteMessageAsync(SseEvent sseEvent)
431434
{
432-
if (sseEvent.Event != "message" || string.IsNullOrEmpty(sseEvent.Data))
435+
if (string.IsNullOrEmpty(sseEvent.Data))
433436
{
434437
return;
435438
}

0 commit comments

Comments
 (0)