Spec: the complete environment goes to the SDK with InheritEnvironmentVariables=false instead of nulls; the cache key also covers cwd and prefix.
41 lines
1.5 KiB
C#
41 lines
1.5 KiB
C#
using System.Text.RegularExpressions;
|
|
|
|
namespace Volcanic.AgenticCore.Extensions.Mcp;
|
|
|
|
/// <summary>
|
|
/// Exposed tool names: <c>prefix + mcpName</c>, characters outside <c>[A-Za-z0-9_-]</c> replaced by <c>_</c>, at most 48
|
|
/// characters so the Claude Code provider's <c>ToolCatalog</c> keeps them readable, duplicates suffixed <c>_2</c>, <c>_3</c>.
|
|
/// </summary>
|
|
internal static partial class ToolNaming
|
|
{
|
|
public const int MaxLength = 48;
|
|
|
|
public static string Sanitize(string? prefix, string mcpName)
|
|
{
|
|
var name = InvalidCharacters().Replace((prefix ?? "") + mcpName, "_");
|
|
if (name.Length == 0) name = "tool";
|
|
return name.Length > MaxLength ? name[..MaxLength] : name;
|
|
}
|
|
|
|
public static IReadOnlyList<string> Expose(IReadOnlyList<string> mcpNames, string? prefix)
|
|
{
|
|
var used = new HashSet<string>(StringComparer.Ordinal);
|
|
var result = new List<string>(mcpNames.Count);
|
|
foreach (var mcpName in mcpNames)
|
|
{
|
|
var baseName = Sanitize(prefix, mcpName);
|
|
var name = baseName;
|
|
for (var n = 2; !used.Add(name); n++)
|
|
{
|
|
var suffix = $"_{n}";
|
|
name = (baseName.Length + suffix.Length > MaxLength ? baseName[..(MaxLength - suffix.Length)] : baseName) + suffix;
|
|
}
|
|
result.Add(name);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
[GeneratedRegex("[^A-Za-z0-9_-]")]
|
|
private static partial Regex InvalidCharacters();
|
|
}
|