8000 Add permission workflow support for custom tools (AIFunctionFactory/defineTool) by Copilot · Pull Request #265 · github/copilot-sdk · GitHub
[go: up one dir, main page]

Skip to content

Conversation

Copy link
Contributor
Copilot AI commented Jan 29, 2026

Custom tools defined via AIFunctionFactory/defineTool bypassed the OnPermissionRequest handler and executed automatically, unlike built-in tools (file ops, shell commands) which properly request permission.

Changes

All SDKs

  • Added requiresApproval field to tool definitions (default: false)
  • Tool execution now checks permission before invocation when requiresApproval: true
  • Added "tool" to PermissionRequest kind union with toolName field
  • Permission denials return "denied" result type to LLM

SDK-specific

  • Node.js: Added requiresApproval?: boolean to Tool interface and defineTool helper
  • .NET: Created CopilotTool wrapper type with RequiresApproval property; SessionConfig.Tools accepts ICollection<object> (both AIFunction and CopilotTool)
  • Python: Added requires_approval: bool to Tool dataclass and define_tool decorator
  • Go: Added RequiresApproval bool to Tool struct

Usage

// Node.js
const deleteTool = defineTool("delete_file", {
    description: "Deletes a file",
    parameters: z.object({ path: z.string() }),
    handler: async ({ path }) => fs.unlink(path),
    requiresApproval: true  // Permission required
});

const session = await client.createSession({
    tools: [deleteTool],
    onPermissionRequest: (request) => {
        if (request.kind === "tool") {
            console.log(`Tool: ${request.toolName}`);
            return { kind: "approved" }; // or "denied-interactively-by-user"
        }
        return { kind: "approved" };
    }
});
// .NET
var deleteTool = new CopilotTool
{
    Function = AIFunctionFactory.Create(DeleteFile, "delete_file"),
    RequiresApproval = true
};

var session = await client.CreateSessionAsync(new SessionConfig
{
    Tools = [deleteTool],
    OnPermissionRequest = (request, invocation) => {
        if (request.Kind == "tool") 
            return PromptUser(request.ExtensionData["toolName"]);
        return Task.FromResult(new PermissionRequestResult { Kind = "approved" });
    }
});

Backward compatible: tools without requiresApproval execute automatically as before.

Original prompt

This section details on the original issue you should resolve

<issue_title>AIFunctionFactory Tools does not go through permission handler | Dotnet | NodeJS</issue_title>
<issue_description>Issue: Tools defined through AIFunctionFactory does not follow approval or permission workflow and are invoked automatically. There should be an option to specify permissionRequired within the tool definition and they should seek permission from user before invoking the tool if not specified otherwise.

// Define a tool that Copilot can call
var getWeather = AIFunctionFactory.Create(
    ([Description("The city name")] string city) =>
    {
        // In a real app, you'd call a weather API here
        var conditions = new[] { "sunny", "cloudy", "rainy", "partly cloudy" };
        var temp = Random.Shared.Next(50, 80);
        var condition = conditions[Random.Shared.Next(conditions.Length)];
        return new { city, temperature = $"{temp}°F", condition };
    },
    "get_weather",
    "Get the current weather for a city"
);

await using var client = new CopilotClient(new CopilotClientOptions { LogLevel = "all" });
await using var session = await client.CreateSessionAsync(new SessionConfig
{
    Model = "gpt-5.2",
    Streaming = true,
    Tools = [getWeather],
    OnPermissionRequest = async (permissionRequest, permissionInvocation) =>
    {
        Console.WriteLine($"\n⚠️ Permission Requested: {permissionRequest.Kind}");
        Console.WriteLine($"   Details: {System.Text.Json.JsonSerializer.Serialize(permissionRequest.ExtensionData)}");

        // For custom tools, ask the user
        Console.Write("Allow? (Y/N): ");
        var response = Console.ReadLine();
        if (string.Equals(response, "Y", StringComparison.OrdinalIgnoreCase))
        {
            return await Task.FromResult(new PermissionRequestResult { Kind = "approved" });
        }
        else
        {
            return await Task.FromResult(new PermissionRequestResult { Kind = "denied-interactively-by-user" });
        }
    }
});

Expected Behaviur: All tool invocations by the assistant, regardless of their implementation, must follow permission workflow and go through permission handler unless stated otherwise. AIFunctionFactory should also expose a property to set whether permission required or not. For example, approvalMode set to AutoApproved or NeverRequire or Always etc.

Output:

You: Whats the weather in Sambhal
Assistant: I’m fetching the current weather for Sambhal. Sambhal weather right now: **58°F (cloudy)**.

SDK tested: NodeJS and Dotnet with version 0.1.19
</issue_description>

<agent_instructions>Investigate the users reported issue across all SDK versions and propose a fix. </agent_instructions>

Comments on the Issue (you are @copilot in this section)


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Co-authored-by: patniko <26906478+patniko@users.noreply.github.com>
Copilot AI and others added 2 commits January 29, 2026 17:54
Co-authored-by: patniko <26906478+patniko@users.noreply.github.com>
Co-authored-by: patniko <26906478+patniko@users.noreply.github.com>
@stephentoub
Copy link
Contributor

…th AIFunction and CopilotTool

Co-authored-by: patniko <26906478+patniko@users.noreply.github.com>
…dation, fix Node.js docs

Co-authored-by: patniko <26906478+patniko@users.noreply.github.com>
Comment on lines +961 to +969
catch
{
// If permission handler fails or is not configured, deny the tool execution
return new ToolCallResponse(new ToolResultObject
{
TextResultForLlm = "Tool execution requires permission but no permission handler is configured.",
ResultType = "denied"
});
}
Copilot AI changed the title [WIP] Add permission handling for AIFunctionFactory tools Add permission workflow support for custom tools (AIFunctionFactory/defineTool) Jan 29, 2026
Copilot AI requested a review from patniko January 29, 2026 18:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

AIFunctionFactory Tools does not go through permission handler | Dotnet | NodeJS

3 participants

0