/*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. *--------------------------------------------------------------------------------------------*/ using System.Text.RegularExpressions; namespace GitHub.Copilot; /// /// Builder for / /// using source-qualified filter /// patterns (builtin:*, mcp:<name>, custom:*, etc.). /// /// /// /// Tools are classified by the runtime at registration time (not from name /// parsing), so AddBuiltIn("foo") 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. /// /// /// inherits from List<string>, so instances /// can be assigned directly to /// or . /// /// /// /// /// var session = await client.CreateSessionAsync(new SessionConfig /// { /// AvailableTools = new ToolSet() /// .AddBuiltIn(BuiltInTools.Isolated) /// .AddMcp("*") /// .AddCustom("*"), /// }); /// /// public sealed class ToolSet : List { private static readonly Regex s_validToolName = new(@"^[a-zA-Z0-9_-]+$", RegexOptions.Compiled); /// /// Adds one or more built-in tool patterns. /// /// A specific built-in tool name (e.g. "bash") or /// "*" to match all built-in tools. /// This for chaining. public ToolSet AddBuiltIn(string name) { ValidateName("builtin", name); Add($"builtin:{name}"); return this; } /// /// Adds a list of built-in tool patterns /// (e.g. ). /// /// Built-in tool names to add. /// This for chaining. public ToolSet AddBuiltIn(IEnumerable names) { ArgumentNullException.ThrowIfNull(names); foreach (var name in names) { AddBuiltIn(name); } return this; } /// /// Adds a custom tool pattern. Matches tools registered via the SDK's /// option or via custom agents. /// /// A specific custom tool name or "*" to match /// all custom tools. /// This for chaining. public ToolSet AddCustom(string name) { ValidateName("custom", name); Add($"custom:{name}"); return this; } /// /// Adds an MCP tool pattern. Matches tools advertised by any configured /// MCP server. /// /// The runtime's canonical wire name for the MCP /// tool (e.g. "github-list_issues"), or "*" to match all /// MCP tools from any server. /// This for chaining. 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)); } } } /// /// Curated sets of built-in tool names for common scenarios. Each constant is /// meant to be passed to . /// public static class BuiltInTools { /// /// 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 /// scenarios (e.g. multi-tenant /// servers) without leaking host capabilities. /// /// /// /// Contract: 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. /// /// public static IReadOnlyList Isolated { get; } = [ "ask_user", "task_complete", "exit_plan_mode", "task", "read_agent", "write_agent", "list_agents", "send_inbox", "context_board", "skill", ]; }