# How the Copilot SDK Handles Different Code Contexts: System Prompt Architecture Explained

> Learn how the Copilot SDK handles code contexts. Discover its system prompt architecture, managing environment, Git state, and files for better development insights.

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

---

**The Copilot SDK assembles code context into named system prompt sections—like `environment_context` and `code_change_rules`—that describe the working directory, Git state, available tools, and repository files, allowing developers to inspect, override, or remove each section via `SystemMessageConfig`.**

The `github/copilot-sdk` repository provides a flexible runtime environment for building Copilot-powered applications. When the Copilot SDK handles different code contexts, it constructs a dynamic **system prompt** that captures the current state of the file system, version control, and available tooling, then exposes fine-grained controls for customizing what the model sees.

## System Prompt Architecture

The SDK organizes all contextual information into a set of **named sections** defined in the `SYSTEM_MESSAGE_SECTIONS` constant. In [`nodejs/src/types.ts`](https://github.com/github/copilot-sdk/blob/main/nodejs/src/types.ts) (line 969), this catalog maps identifiers to distinct parts of the prompt, including `environment_context`, `code_change_rules`, and `tool_instructions`.

Each section is generated automatically from the runtime state and injected into the final prompt sent to the model. This modular design ensures that the Copilot SDK can expose rich code context while keeping each concern isolated and configurable.

### Named Sections and Identifiers

The `SystemMessageSection` type defines the fixed list of available sections. The most critical section for code context is `environment_context`, which aggregates working directory information, OS details, Git root, file listings, and available tools. Other sections handle skill-specific metadata, tool instructions, and code change guidelines.

## Environment Context Generation

The **environment context** serves as the primary source of truth for the model's understanding of the codebase. According to the source code in [`nodejs/src/types.ts`](https://github.com/github/copilot-sdk/blob/main/nodejs/src/types.ts) (line 978), this section includes:

- Current working directory
- Operating system information
- Git repository root
- Directory file listings
- Available tool definitions

The SDK generates this context automatically at session initialization and updates it when the application records context changes. This ensures the model always reasons against the actual state of the file system.

## Skill Context and Metadata Handling

When applications use **skills** (reusable tool bundles), the SDK injects a `<skill-context>` block containing the skill’s base directory and content. The SDK sanitizes this metadata before it reaches the user interface.

As demonstrated in [`test/harness/replayingCapiProxy.test.ts`](https://github.com/github/copilot-sdk/blob/main/test/harness/replayingCapiProxy.test.ts) (line 428), the SDK strips skill-context blocks from user messages to prevent leaking implementation details. This separation keeps the model's reasoning context rich while maintaining clean conversation history.

## Customizing Context with SystemMessageConfig

Developers control how the SDK handles different code contexts through the `SystemMessageConfig` interface defined in [`nodejs/src/types.ts`](https://github.com/github/copilot-sdk/blob/main/nodejs/src/types.ts) (line 860). The SDK supports three distinct modes:

- **Append mode**: Adds custom content to the default system message
- **Replace mode**: Substitutes the entire system message with custom content
- **Customize mode**: Modifies individual sections using specific actions

In **customize mode**, each section supports five actions: `replace`, `remove`, `append`, `prepend`, or a **transform callback** that receives the current section content and returns modified text.

### Removing Sensitive Context

For privacy-sensitive applications, you can completely remove the `environment_context` section:

```typescript
import { CopilotClient, RuntimeConnection } from "copilot-sdk";

const client = new CopilotClient({
  connection: RuntimeConnection.forStdio(),
  systemMessage: {
    mode: "customize",
    sections: {
      environment_context: { action: "remove" },
    },
  },
});

```

### Appending Custom Rules

To inject project-specific guidelines into the `code_change_rules` section:

```typescript
const clientWithNotes = new CopilotClient({
  connection: RuntimeConnection.forStdio(),
  systemMessage: {
    mode: "customize",
    sections: {
      code_change_rules: {
        action: "append",
        content: "\nPlease prefer TypeScript over JavaScript.",
      },
    },
  },
});

```

### Dynamic Context Transformation

For computed context—such as recently changed files—you can provide an async transform function:

```typescript
async function listChangedFiles(): Promise<string> {
  // Implementation to detect modified files
  return "changed_files: file1.ts, file2.ts";
}

const clientDynamic = new CopilotClient({
  connection: RuntimeConnection.forStdio(),
  systemMessage: {
    mode: "customize",
    sections: {
      environment_context: {
        action: async (current) => `${current}\n${await listChangedFiles()}`,
      },
    },
  },
});

```

## Context Propagation and Session Management

The SDK ensures context remains consistent across tool invocations and session state changes. The `ToolInvocation` interface (defined in [`nodejs/src/types.ts`](https://github.com/github/copilot-sdk/blob/main/nodejs/src/types.ts), line 790) carries the current `environment_context` to hooks like `onPreToolUse`, allowing middleware to access the working directory and repository state.

For **session-level context changes**—such as switching Git branches—applications call `session.rpc.metadata.recordContextChange`. The SDK then emits a `session.context_changed` event, updating the model's view of the environment. The end-to-end test in [`nodejs/test/e2e/rpc_session_state.e2e.test.ts`](https://github.com/github/copilot-sdk/blob/main/nodejs/test/e2e/rpc_session_state.e2e.test.ts) (line 368) demonstrates this mechanism, verifying that context changes propagate correctly through the RPC layer.

## Summary

- The Copilot SDK structures code context into **named system prompt sections** defined in `SYSTEM_MESSAGE_SECTIONS` ([`nodejs/src/types.ts`](https://github.com/github/copilot-sdk/blob/main/nodejs/src/types.ts)).
- The `environment_context` section captures the working directory, Git root, OS info, and available tools automatically.
- **Skill context** blocks are injected for tool bundles but stripped from user messages to hide implementation details.
- Developers customize context exposure via `SystemMessageConfig` using **append**, **replace**, or **customize** modes, with per-section actions including transform callbacks.
- Context propagates to tool invocations through the `ToolInvocation` interface and updates dynamically via `recordContextChange` events.

## Frequently Asked Questions

### What sections make up the system prompt in the Copilot SDK?

The system prompt consists of predefined sections identified by the `SystemMessageSection` type, including `environment_context` (working directory and files), `code_change_rules` (coding guidelines), `tool_instructions` (available tools), and skill-specific metadata blocks. The full catalog resides in the `SYSTEM_MESSAGE_SECTIONS` constant at [`nodejs/src/types.ts`](https://github.com/github/copilot-sdk/blob/main/nodejs/src/types.ts) (line 969).

### How can I prevent sensitive files from appearing in the Copilot context?

Use the `customize` mode in `SystemMessageConfig` with the `remove` action on the `environment_context` section. This prevents the SDK from injecting file system details, Git state, or tool listings into the system prompt, though it limits the model's awareness of the project structure.

### What is the difference between append and customize modes in SystemMessageConfig?

**Append mode** adds your custom content to the end of the SDK's default system message while preserving all automatically generated sections. **Customize mode** provides surgical control, allowing you to `replace`, `remove`, `append`, `prepend`, or transform individual sections independently without affecting other parts of the prompt.

### How does the SDK handle context when switching Git branches during a session?

Applications call `session.rpc.metadata.recordContextChange` to notify the SDK of environment changes. The SDK emits a `session.context_changed` event that updates the `environment_context` section with the new branch, file listings, and working directory state, ensuring the model reasons against the current codebase rather than stale data.