Adding support for returning collections from tools (#116)
* Adding support for returning collections from tools This will mean we can return multiple AIContent objects from a tool, such as a mixed text/image set Contributes to #68 * Code review feedback * Adding tests and some more cases * More cases in switch and tests
This commit is contained in:
parent
5171ccc3c3
commit
3c72c348d6
2 changed files with 260 additions and 47 deletions
|
|
@ -1,7 +1,9 @@
|
|||
using Microsoft.Extensions.AI;
|
||||
using ModelContextProtocol.Protocol.Types;
|
||||
using ModelContextProtocol.Utils;
|
||||
using ModelContextProtocol.Utils.Json;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace ModelContextProtocol;
|
||||
|
||||
|
|
@ -101,4 +103,28 @@ public static class AIContentExtensions
|
|||
Convert.ToBase64String(dataContent.Data.ToArray());
|
||||
#endif
|
||||
}
|
||||
|
||||
internal static Content ToContent(this AIContent content) =>
|
||||
content switch
|
||||
{
|
||||
TextContent textContent => new()
|
||||
{
|
||||
Text = textContent.Text,
|
||||
Type = "text",
|
||||
},
|
||||
DataContent dataContent => new()
|
||||
{
|
||||
Data = dataContent.GetBase64Data(),
|
||||
MimeType = dataContent.MediaType,
|
||||
Type =
|
||||
dataContent.HasTopLevelMediaType("image") ? "image" :
|
||||
dataContent.HasTopLevelMediaType("audio") ? "audio" :
|
||||
"resource",
|
||||
},
|
||||
_ => new()
|
||||
{
|
||||
Text = JsonSerializer.Serialize(content, McpJsonUtilities.DefaultOptions.GetTypeInfo(typeof(object))),
|
||||
Type = "text",
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ internal sealed class AIFunctionMcpServerTool : McpServerTool
|
|||
public static new AIFunctionMcpServerTool Create(
|
||||
Delegate method,
|
||||
string? name,
|
||||
string? description,
|
||||
string? description,
|
||||
IServiceProvider? services)
|
||||
{
|
||||
Throw.IfNull(method);
|
||||
|
|
@ -34,7 +34,7 @@ internal sealed class AIFunctionMcpServerTool : McpServerTool
|
|||
/// Creates an <see cref="McpServerTool"/> instance for a method, specified via a <see cref="Delegate"/> instance.
|
||||
/// </summary>
|
||||
public static new AIFunctionMcpServerTool Create(
|
||||
MethodInfo method,
|
||||
MethodInfo method,
|
||||
object? target,
|
||||
string? name,
|
||||
string? description,
|
||||
|
|
@ -195,57 +195,49 @@ internal sealed class AIFunctionMcpServerTool : McpServerTool
|
|||
};
|
||||
}
|
||||
|
||||
switch (result)
|
||||
return result switch
|
||||
{
|
||||
case null:
|
||||
return new()
|
||||
{
|
||||
Content = []
|
||||
};
|
||||
|
||||
case string text:
|
||||
return new()
|
||||
{
|
||||
Content = [new() { Text = text, Type = "text" }]
|
||||
};
|
||||
|
||||
case TextContent textContent:
|
||||
return new()
|
||||
{
|
||||
Content = [new() { Text = textContent.Text, Type = "text" }]
|
||||
};
|
||||
|
||||
case DataContent dataContent:
|
||||
return new()
|
||||
{
|
||||
Content = [new()
|
||||
{
|
||||
Data = dataContent.GetBase64Data(),
|
||||
MimeType = dataContent.MediaType,
|
||||
Type = dataContent.HasTopLevelMediaType("image") ? "image" : "resource",
|
||||
}]
|
||||
};
|
||||
|
||||
case string[] texts:
|
||||
return new()
|
||||
{
|
||||
Content = texts
|
||||
.Select(x => new Content() { Type = "text", Text = x ?? string.Empty })
|
||||
.ToList()
|
||||
};
|
||||
AIContent aiContent => new()
|
||||
{
|
||||
Content = [aiContent.ToContent()]
|
||||
},
|
||||
null => new()
|
||||
{
|
||||
Content = []
|
||||
},
|
||||
string text => new()
|
||||
{
|
||||
Content = [new() { Text = text, Type = "text" }]
|
||||
},
|
||||
Content content => new()
|
||||
{
|
||||
Content = [content]
|
||||
},
|
||||
IEnumerable<string> texts => new()
|
||||
{
|
||||
Content = [.. texts.Select(x => new Content() { Type = "text", Text = x ?? string.Empty })]
|
||||
},
|
||||
IEnumerable<AIContent> contentItems => new()
|
||||
{
|
||||
Content = [.. contentItems.Select(static item => item.ToContent())]
|
||||
},
|
||||
IEnumerable<Content> contents => new()
|
||||
{
|
||||
Content = [.. contents]
|
||||
},
|
||||
CallToolResponse callToolResponse => callToolResponse,
|
||||
|
||||
// TODO https://github.com/modelcontextprotocol/csharp-sdk/issues/69:
|
||||
// Add specialization for annotations.
|
||||
|
||||
default:
|
||||
return new()
|
||||
{
|
||||
Content = [new()
|
||||
_ => new()
|
||||
{
|
||||
Content = [new()
|
||||
{
|
||||
Text = JsonSerializer.Serialize(result, McpJsonUtilities.DefaultOptions.GetTypeInfo(typeof(object))),
|
||||
Type = "text"
|
||||
}]
|
||||
};
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in a new issue