Skip to main content
Skip to content

Changing tools during a session

An application can replace the tools it supplies to a live session without recreating it. For example, a web page can offer different tools as the user navigates, or a client that takes over a session can bring its own tools. Each SDK replaces the client's complete tool set and the handlers that serve it in one call.

Experimental. Tool replacement wraps the experimental session.tools.set RPC and requires a runtime that supports it.

Replace this client's tools

Pass the complete set of tools this client should supply. It replaces the tools the client supplied when the session was created or resumed, or in an earlier replacement. Built-in, MCP, and plugin tools, and tools that other clients connected to the same session supply, are unaffected. Pass an empty list to remove all of this client's tools.

Tools are defined exactly as they are for creating a session, and a tool without a handler behaves the same way it does there.

코드 언어 navigation

TypeScript
import { defineTool } from "@github/copilot-sdk";
import { z } from "zod";

const searchIssues = defineTool("search_issues", {
    description: "Search the issues shown on the current page",
    parameters: z.object({ query: z.string().describe("Search text") }),
    handler: async ({ query }) => findIssues(query),
});

// Supply only the tools the current page provides.
await session.setTools([searchIssues]);

// Remove all of this client's tools.
await session.setTools([]);

When the new tools take effect

  • Model requests. The runtime offers the new tools from the agent's next model request. That request can be part of a turn that is already in progress.
  • Handlers. As soon as the runtime accepts the replacement, every tool call the session dispatches uses the new handlers. Calls that are already running finish on the handlers that started them.
  • Rejection. If the runtime rejects the replacement, the call fails and the previous tools and handlers stay in place. The runtime rejects tool names with invalid characters and names that another connected client already supplies.
  • Ordering. Concurrent replacements on the same session are applied one at a time, in the order they're made.
  • Cancellation. In SDKs that let you cancel the call, cancelling it while an earlier replacement is still in flight sends nothing. Once the request is sent, cancelling only stops the wait: if the runtime accepts the replacement, the new handlers still take effect.

Replacing tools during a turn

A model request that is already in flight was made with the previous tools, so the agent can still call a tool you just removed. The session doesn't answer that call, because another connected client might supply a tool with the same name, so the call can stay pending until the turn is aborted.

If a running turn might still call a tool you remove, replace tools while the session is idle, for example after the session.idle event, or abort the turn first. Replacing a tool's handler under the same name is safe during a turn: calls dispatched after the runtime accepts the replacement use the new handler.

SDK reference

SDKMethod
TypeScriptsession.setTools(tools)
Pythonawait session.set_tools(tools)
Gosession.SetTools(ctx, tools)
.NETawait session.SetToolsAsync(tools, cancellationToken)
Javasession.setTools(tools), which returns a CompletableFuture<Void>
Rustsession.set_tools(tools).await