# How to Handle Copilot Suggestions and Responses Using the Copilot SDK

> Learn how to handle Copilot suggestions and responses with the Copilot SDK. Instantiate a CopilotClient, create a CopilotSession, and subscribe to events for seamless integration and control.

- Repository: [GitHub/copilot-sdk](https://github.com/github/copilot-sdk)
- Tags: how-to-guide
- Published: 2026-07-20

---

**To handle Copilot suggestions and responses, instantiate a `CopilotClient` to manage the runtime connection, create a `CopilotSession` to maintain conversation state, and subscribe to typed events like `assistant.message` and `external_tool.requested` to process the assistant's output and tool calls.**

The GitHub Copilot SDK provides a Node.js interface for programmatically driving Copilot CLI sessions, enabling applications to send prompts and handle Copilot suggestions and responses through a JSON-RPC bridge. The architecture separates concerns between the `CopilotClient` class in [[`nodejs/src/index.ts`](https://github.com/github/copilot-sdk/blob/main/nodejs/src/index.ts)](https://github.com/github/copilot-sdk/blob/main/nodejs/src/index.ts), which handles global lifecycle and configuration, and the `CopilotSession` class implemented in [[`nodejs/src/session.ts`](https://github.com/github/copilot-sdk/blob/main/nodejs/src/session.ts)](https://github.com/github/copilot-sdk/blob/main/nodejs/src/session.ts) (lines 33-34), which manages individual conversation state, event emission, and capability negotiation.

## Initialize the Client and Create a Session

The workflow begins with the `CopilotClient` entry point, which configures how the SDK communicates with the Copilot runtime via stdio, TCP, or in-process connections. Calling `new CopilotClient()` initializes the configuration, while `client.start()` spawns the runtime and establishes the JSON-RPC channel (`createSessionRpc` in [[`session.ts`](https://github.com/github/copilot-sdk/blob/main/session.ts)](https://github.com/github/copilot-sdk/blob/main/nodejs/src/session.ts) lines 81-86).

To begin handling suggestions, create a session using `client.createSession()`, which instantiates the `CopilotSession` class (lines 165-173). The session object stores event listeners, tool registries, and UI capabilities, providing the primary interface for sending prompts and receiving responses.

```typescript
import { CopilotClient, approveAll } from "@github/copilot-sdk";

const client = new CopilotClient();  // defaults to stdio
await client.start();

const session = await client.createSession({
  model: "gpt-4o-mini",
  onPermissionRequest: approveAll,  // auto-approve tool use
});

```

## Send Prompts and Listen for Responses

To dispatch a prompt, use the `session.send()` method (defined in [[`session.ts`](https://github.com/github/copilot-sdk/blob/main/session.ts)](https://github.com/github/copilot-sdk/blob/main/nodejs/src/session.ts) lines 44-61), which transmits the message to the Copilot runtime. For synchronous-style execution, `session.sendAndWait()` blocks until the session reaches an idle state.

The SDK exposes an event-driven API via `session.on()` (lines 85-110), supporting typed subscriptions to specific events or wildcard handlers. To capture the assistant's text suggestions, listen for the `assistant.message` event. To detect when processing completes, watch for `session.idle`.

```typescript
// Set up listeners before sending
const done = new Promise<void>((resolve) => {
  session.on("assistant.message", (ev) => {
    console.log("🤖:", ev.data.content);
  });
  session.on("session.idle", () => resolve());
});

await session.send({ prompt: "Explain async/await in JavaScript." });
await done;  // waits until idle

```

## Handle Tool Calls and Permissions

When the assistant requires external data, it emits `external_tool.requested` events. The SDK routes these to registered tool handlers via `_executeToolAndRespond` ([[`session.ts`](https://github.com/github/copilot-sdk/blob/main/session.ts)](https://github.com/github/copilot-sdk/blob/main/nodejs/src/session.ts) lines 608-656), which executes your `ToolHandler` and returns the result via RPC.

Register tools during session creation or via `registerTools` (lines 994-1005). For security, tool execution requires permission approval. Handle `permission.requested` events through `onPermissionRequest` or rely on `_executePermissionAndRespond` (lines 672-690) to approve or deny specific tool invocations.

```typescript
const session = await client.createSession({
  model: "gpt-4o",
  tools: [{
    name: "weather",
    description: "Get current weather",
    handler: async (args) => {
      const { city } = args as { city: string };
      return `Sunny, 23°C in ${city}`;
    }
  }],
  onPermissionRequest: approveAll,
});

session.on("external_tool.requested", (ev) => {
  console.log("Executing:", ev.data.toolName);
});

```

## Process UI Elicitation Requests

When the host supports interactive capabilities, the assistant may request user input through elicitation dialogs. Check `session.capabilities.ui?.elicitation` (capability getter in [[`session.ts`](https://github.com/github/copilot-sdk/blob/main/session.ts)](https://github.com/github/copilot-sdk/blob/main/nodejs/src/session.ts) lines 199-203) to determine UI availability.

The SDK routes `elicitation.requested` events to your handler via `_handleElicitationRequest` (lines 661-667), which invokes UI helpers like `_confirm`, `_select`, and `_input` (lines 545-616) to render dialogs and return user responses.

```typescript
const session = await client.createSession({
  model: "gpt-4",
  onElicitationRequest: async (ctx) => {
    // Returns boolean based on user interaction
    const confirmed = await ctx.session.ui.confirm("Deploy to production?");
    return confirmed ? { action: "accept" } : { action: "cancel" };
  },
});

await session.send({ prompt: "Should we deploy now?" });

```

## Monitor All Events with Wildcard Subscriptions

For debugging or comprehensive logging, subscribe to all session events using a wildcard handler. This receives every event type—including `assistant.message`, `session.error`, `external_tool.requested`, and `permission.requested`—as defined in [[`nodejs/src/generated/session-events.ts`](https://github.com/github/copilot-sdk/blob/main/nodejs/src/generated/session-events.ts)](https://github.com/github/copilot-sdk/blob/main/nodejs/src/generated/session-events.ts).

```typescript
session.on((ev) => {
  console.log(`[${ev.type}]`, ev.data);
});

```

Wildcard subscriptions are processed alongside specific listeners, allowing you to log all traffic while handling specific events with dedicated callbacks.

## Summary

- **Create a `CopilotClient`** to manage the runtime lifecycle and global configuration.
- **Instantiate `CopilotSession`** via `client.createSession()` to maintain conversation state and event handlers.
- **Send prompts** using `session.send()` or `session.sendAndWait()`, then capture output via `assistant.message` events.
- **Register tool handlers** and permission callbacks to manage external tool execution and security approvals.
- **Check capabilities** before invoking UI methods like `session.ui.confirm()` to ensure host support.
- **Use wildcard listeners** for debugging or generic event logging across the entire session lifecycle.

## Frequently Asked Questions

### What is the difference between `send()` and `sendAndWait()`?

The `send()` method (lines 44-61 in [`session.ts`](https://github.com/github/copilot-sdk/blob/main/session.ts)) dispatches a prompt asynchronously and returns immediately, requiring you to listen for `session.idle` to detect completion. In contrast, `sendAndWait()` blocks execution until the session transitions to an idle state, providing a synchronous-style API for simpler scripts.

### How do I automatically approve all tool permissions?

Pass the `approveAll` helper function (exported from [[`nodejs/src/index.ts`](https://github.com/github/copilot-sdk/blob/main/nodejs/src/index.ts)](https://github.com/github/copilot-sdk/blob/main/nodejs/src/index.ts)) to the `onPermissionRequest` option when creating a session. This bypasses the `_executePermissionAndRespond` validation (lines 672-690) and automatically approves every tool invocation.

### Can I use the SDK without UI capabilities?

Yes. UI features are optional and depend on the host runtime configuration. Check `session.capabilities.ui` (lines 199-203 in [`session.ts`](https://github.com/github/copilot-sdk/blob/main/session.ts)) before calling elicitation methods. If unsupported, the assistant will not emit `elicitation.requested` events, and you can rely solely on text-based `assistant.message` events.

### Where are the RPC method signatures defined?

Auto-generated RPC method signatures reside in [[`nodejs/src/generated/rpc.ts`](https://github.com/github/copilot-sdk/blob/main/nodejs/src/generated/rpc.ts)](https://github.com/github/copilot-sdk/blob/main/nodejs/src/generated/rpc.ts), while session event payload definitions are located in [[`nodejs/src/generated/session-events.ts`](https://github.com/github/copilot-sdk/blob/main/nodejs/src/generated/session-events.ts)](https://github.com/github/copilot-sdk/blob/main/nodejs/src/generated/session-events.ts). These generated files provide the type definitions used by the JSON-RPC channel established in [`session.ts`](https://github.com/github/copilot-sdk/blob/main/session.ts) lines 81-86.