-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Expand file tree
/
Copy pathToolSet.cs
More file actions
156 lines (147 loc) · 5.33 KB
/
ToolSet.cs
File metadata and controls
156 lines (147 loc) · 5.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
*--------------------------------------------------------------------------------------------*/
using System.Text.RegularExpressions;
namespace GitHub.Copilot;
/// <summary>
/// Builder for <see cref="SessionConfigBase.AvailableTools"/> /
/// <see cref="SessionConfigBase.ExcludedTools"/> using source-qualified filter
/// patterns (<c>builtin:*</c>, <c>mcp:<name></c>, <c>custom:*</c>, etc.).
/// </summary>
/// <remarks>
/// <para>
/// Tools are classified by the runtime at registration time (not from name
/// parsing), so <c>AddBuiltIn("foo")</c> matches only tools the runtime
/// registered as built-in, even if an MCP server or custom-agent extension
/// happens to register a tool with the same wire name.
/// </para>
/// <para>
/// <see cref="ToolSet"/> inherits from <c>List<string></c>, so instances
/// can be assigned directly to <see cref="SessionConfigBase.AvailableTools"/>
/// or <see cref="SessionConfigBase.ExcludedTools"/>.
/// </para>
/// </remarks>
/// <example>
/// <code>
/// var session = await client.CreateSessionAsync(new SessionConfig
/// {
/// AvailableTools = new ToolSet()
/// .AddBuiltIn(BuiltInTools.Isolated)
/// .AddMcp("*")
/// .AddCustom("*"),
/// });
/// </code>
/// </example>
public sealed class ToolSet : List<string>
{
private static readonly Regex s_validToolName = new(@"^[a-zA-Z0-9_-]+$", RegexOptions.Compiled);
/// <summary>
/// Adds one or more built-in tool patterns.
/// </summary>
/// <param name="name">A specific built-in tool name (e.g. <c>"bash"</c>) or
/// <c>"*"</c> to match all built-in tools.</param>
/// <returns>This <see cref="ToolSet"/> for chaining.</returns>
public ToolSet AddBuiltIn(string name)
{
ValidateName("builtin", name);
Add($"builtin:{name}");
return this;
}
/// <summary>
/// Adds a list of built-in tool patterns
/// (e.g. <see cref="BuiltInTools.Isolated"/>).
/// </summary>
/// <param name="names">Built-in tool names to add.</param>
/// <returns>This <see cref="ToolSet"/> for chaining.</returns>
public ToolSet AddBuiltIn(IEnumerable<string> names)
{
ArgumentNullException.ThrowIfNull(names);
foreach (var name in names)
{
AddBuiltIn(name);
}
return this;
}
/// <summary>
/// Adds a custom tool pattern. Matches tools registered via the SDK's
/// <see cref="SessionConfigBase.Tools"/> option or via custom agents.
/// </summary>
/// <param name="name">A specific custom tool name or <c>"*"</c> to match
/// all custom tools.</param>
/// <returns>This <see cref="ToolSet"/> for chaining.</returns>
public ToolSet AddCustom(string name)
{
ValidateName("custom", name);
Add($"custom:{name}");
return this;
}
/// <summary>
/// Adds an MCP tool pattern. Matches tools advertised by any configured
/// MCP server.
/// </summary>
/// <param name="toolName">The runtime's canonical wire name for the MCP
/// tool (e.g. <c>"github-list_issues"</c>), or <c>"*"</c> to match all
/// MCP tools from any server.</param>
/// <returns>This <see cref="ToolSet"/> for chaining.</returns>
public ToolSet AddMcp(string toolName)
{
ValidateName("mcp", toolName);
Add($"mcp:{toolName}");
return this;
}
private static void ValidateName(string kind, string name)
{
if (string.IsNullOrEmpty(name))
{
throw new ArgumentException(
$"Invalid {kind} tool name: must not be null or empty.",
nameof(name));
}
if (name == "*")
{
return;
}
if (!s_validToolName.IsMatch(name))
{
throw new ArgumentException(
$"Invalid {kind} tool name '{name}': tool names must match /^[a-zA-Z0-9_-]+$/ " +
"or be the wildcard '*'.",
nameof(name));
}
}
}
/// <summary>
/// Curated sets of built-in tool names for common scenarios. Each constant is
/// meant to be passed to <see cref="ToolSet.AddBuiltIn(IEnumerable{string})"/>.
/// </summary>
public static class BuiltInTools
{
/// <summary>
/// Built-in tools that operate only within the bounds of a single session
/// — no host filesystem access outside the session, no cross-session
/// state, no host environment access, no network. Safe to enable in
/// <see cref="CopilotClientMode.Empty"/> scenarios (e.g. multi-tenant
/// servers) without leaking host capabilities.
/// </summary>
/// <remarks>
/// <para>
/// <b>Contract:</b> tools in this set MUST NOT be extended (even behind
/// options or args) to read or write state outside the session boundary.
/// Adding cross-session or host-state behavior to one of these tools is a
/// breaking change that requires removing it from this set.
/// </para>
/// </remarks>
public static IReadOnlyList<string> Isolated { get; } =
[
"ask_user",
"task_complete",
"exit_plan_mode",
"task",
"read_agent",
"write_agent",
"list_agents",
"send_inbox",
"context_board",
"skill",
];
}