Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 23 additions & 1 deletion docs/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -1245,7 +1245,7 @@ const session = await client.createSession({

### Customize the System Message

Control the AI's behavior and personality:
Control the AI's behavior and personality by appending instructions:

```typescript
const session = await client.createSession({
Expand All @@ -1255,6 +1255,28 @@ const session = await client.createSession({
});
```

For more fine-grained control, use `mode: "customize"` to override individual sections of the system prompt while preserving the rest:

```typescript
const session = await client.createSession({
systemMessage: {
mode: "customize",
sections: {
tone: { action: "replace", content: "Respond in a warm, professional tone. Be thorough in explanations." },
code_change_rules: { action: "remove" },
guidelines: { action: "append", content: "\n* Always cite data sources" },
},
content: "Focus on financial analysis and reporting.",
},
});
```

Available section IDs: `identity`, `tone`, `tool_efficiency`, `environment_context`, `code_change_rules`, `guidelines`, `safety`, `tool_instructions`, `custom_instructions`.

Each override supports four actions: `replace`, `remove`, `append`, and `prepend`. Unknown section IDs are handled gracefully — content is appended to additional instructions and a warning is emitted; `remove` on unknown sections is silently ignored.

See the language-specific SDK READMEs for examples in [TypeScript](../nodejs/README.md), [Python](../python/README.md), [Go](../go/README.md), and [C#](../dotnet/README.md).

---

## Connecting to an External CLI Server
Expand Down
28 changes: 28 additions & 0 deletions dotnet/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,34 @@ var session = await client.CreateSessionAsync(new SessionConfig
});
```

#### Customize Mode

Use `Mode = SystemMessageMode.Customize` to selectively override individual sections of the prompt while preserving the rest:

```csharp
var session = await client.CreateSessionAsync(new SessionConfig
{
Model = "gpt-5",
SystemMessage = new SystemMessageConfig
{
Mode = SystemMessageMode.Customize,
Sections = new Dictionary<string, SectionOverride>
{
[SystemPromptSections.Tone] = new() { Action = SectionOverrideAction.Replace, Content = "Respond in a warm, professional tone. Be thorough in explanations." },
[SystemPromptSections.CodeChangeRules] = new() { Action = SectionOverrideAction.Remove },
[SystemPromptSections.Guidelines] = new() { Action = SectionOverrideAction.Append, Content = "\n* Always cite data sources" },
},
Content = "Focus on financial analysis and reporting."
}
});
```

Available section IDs are defined as constants on `SystemPromptSections`: `Identity`, `Tone`, `ToolEfficiency`, `EnvironmentContext`, `CodeChangeRules`, `Guidelines`, `Safety`, `ToolInstructions`, `CustomInstructions`.

Each section override supports four actions: `Replace`, `Remove`, `Append`, and `Prepend`. Unknown section IDs are handled gracefully: content is appended to additional instructions, and `Remove` overrides are silently ignored.

#### Replace Mode

For full control (removes all guardrails), use `Mode = SystemMessageMode.Replace`:

```csharp
Expand Down
1 change: 1 addition & 0 deletions dotnet/src/Client.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1646,6 +1646,7 @@ private static LogLevel MapLevel(TraceEventType eventType)
[JsonSerializable(typeof(ProviderConfig))]
[JsonSerializable(typeof(ResumeSessionRequest))]
[JsonSerializable(typeof(ResumeSessionResponse))]
[JsonSerializable(typeof(SectionOverride))]
[JsonSerializable(typeof(SessionMetadata))]
[JsonSerializable(typeof(SystemMessageConfig))]
[JsonSerializable(typeof(ToolCallResponseV2))]
Expand Down
5 changes: 1 addition & 4 deletions dotnet/src/SdkProtocolVersion.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,5 @@ internal static class SdkProtocolVersion
/// <summary>
/// Gets the SDK protocol version.
/// </summary>
public static int GetVersion()
{
return Version;
}
public static int GetVersion() => Version;
}
79 changes: 76 additions & 3 deletions dotnet/src/Types.cs
Original file line number Diff line number Diff line change
Expand Up @@ -912,7 +912,71 @@ public enum SystemMessageMode
Append,
/// <summary>Replace the default system message entirely.</summary>
[JsonStringEnumMemberName("replace")]
Replace
Replace,
/// <summary>Override individual sections of the system prompt.</summary>
[JsonStringEnumMemberName("customize")]
Customize
}

/// <summary>
/// Specifies the operation to perform on a system prompt section.
/// </summary>
[JsonConverter(typeof(JsonStringEnumConverter<SectionOverrideAction>))]
public enum SectionOverrideAction
{
/// <summary>Replace the section content entirely.</summary>
[JsonStringEnumMemberName("replace")]
Replace,
/// <summary>Remove the section from the prompt.</summary>
[JsonStringEnumMemberName("remove")]
Remove,
/// <summary>Append content after the existing section.</summary>
[JsonStringEnumMemberName("append")]
Append,
/// <summary>Prepend content before the existing section.</summary>
[JsonStringEnumMemberName("prepend")]
Prepend
}

/// <summary>
/// Override operation for a single system prompt section.
/// </summary>
public class SectionOverride
{
/// <summary>
/// The operation to perform on this section.
/// </summary>
public SectionOverrideAction Action { get; set; }

/// <summary>
/// Content for the override. Optional for all actions. Ignored for remove.
/// </summary>
public string? Content { get; set; }
}

/// <summary>
/// Known system prompt section identifiers for the "customize" mode.
/// </summary>
public static class SystemPromptSections
{
/// <summary>Agent identity preamble and mode statement.</summary>
public const string Identity = "identity";
/// <summary>Response style, conciseness rules, output formatting preferences.</summary>
public const string Tone = "tone";
/// <summary>Tool usage patterns, parallel calling, batching guidelines.</summary>
public const string ToolEfficiency = "tool_efficiency";
/// <summary>CWD, OS, git root, directory listing, available tools.</summary>
public const string EnvironmentContext = "environment_context";
/// <summary>Coding rules, linting/testing, ecosystem tools, style.</summary>
public const string CodeChangeRules = "code_change_rules";
/// <summary>Tips, behavioral best practices, behavioral guidelines.</summary>
public const string Guidelines = "guidelines";
/// <summary>Environment limitations, prohibited actions, security policies.</summary>
public const string Safety = "safety";
/// <summary>Per-tool usage instructions.</summary>
public const string ToolInstructions = "tool_instructions";
/// <summary>Repository and organization custom instructions.</summary>
public const string CustomInstructions = "custom_instructions";
}

/// <summary>
Expand All @@ -921,13 +985,21 @@ public enum SystemMessageMode
public class SystemMessageConfig
{
/// <summary>
/// How the system message is applied (append or replace).
/// How the system message is applied (append, replace, or customize).
/// </summary>
public SystemMessageMode? Mode { get; set; }

/// <summary>
/// Content of the system message.
/// Content of the system message. Used by append and replace modes.
/// In customize mode, additional content appended after all sections.
/// </summary>
public string? Content { get; set; }

/// <summary>
/// Section-level overrides for customize mode.
/// Keys are section identifiers (see <see cref="SystemPromptSections"/>).
/// </summary>
public Dictionary<string, SectionOverride>? Sections { get; set; }
}

/// <summary>
Expand Down Expand Up @@ -2005,6 +2077,7 @@ public class SetForegroundSessionResponse
[JsonSerializable(typeof(SessionLifecycleEvent))]
[JsonSerializable(typeof(SessionLifecycleEventMetadata))]
[JsonSerializable(typeof(SessionListFilter))]
[JsonSerializable(typeof(SectionOverride))]
[JsonSerializable(typeof(SessionMetadata))]
[JsonSerializable(typeof(SetForegroundSessionResponse))]
[JsonSerializable(typeof(SystemMessageConfig))]
Expand Down
5 changes: 4 additions & 1 deletion go/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,10 @@ Event types: `SessionLifecycleCreated`, `SessionLifecycleDeleted`, `SessionLifec
- `ReasoningEffort` (string): Reasoning effort level for models that support it ("low", "medium", "high", "xhigh"). Use `ListModels()` to check which models support this option.
- `SessionID` (string): Custom session ID
- `Tools` ([]Tool): Custom tools exposed to the CLI
- `SystemMessage` (\*SystemMessageConfig): System message configuration
- `SystemMessage` (\*SystemMessageConfig): System message configuration. Supports three modes:
- **append** (default): Appends `Content` after the SDK-managed prompt
- **replace**: Replaces the entire prompt with `Content`
- **customize**: Selectively override individual sections via `Sections` map (keys: `SectionIdentity`, `SectionTone`, `SectionToolEfficiency`, `SectionEnvironmentContext`, `SectionCodeChangeRules`, `SectionGuidelines`, `SectionSafety`, `SectionToolInstructions`, `SectionCustomInstructions`; values: `SectionOverride` with `Action` and optional `Content`)
- `Provider` (\*ProviderConfig): Custom API provider configuration (BYOK). See [Custom Providers](#custom-providers) section.
- `Streaming` (bool): Enable streaming delta events
- `InfiniteSessions` (\*InfiniteSessionConfig): Automatic context compaction configuration
Expand Down
33 changes: 29 additions & 4 deletions go/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,27 @@ func Float64(v float64) *float64 {
return &v
}

// Known system prompt section identifiers for the "customize" mode.
const (
SectionIdentity = "identity"
SectionTone = "tone"
SectionToolEfficiency = "tool_efficiency"
SectionEnvironmentContext = "environment_context"
SectionCodeChangeRules = "code_change_rules"
SectionGuidelines = "guidelines"
SectionSafety = "safety"
SectionToolInstructions = "tool_instructions"
SectionCustomInstructions = "custom_instructions"
)

// SectionOverride defines an override operation for a single system prompt section.
type SectionOverride struct {
// Action is the operation to perform: "replace", "remove", "append", or "prepend".
Action string `json:"action"`
// Content for the override. Optional for all actions. Ignored for "remove".
Content string `json:"content,omitempty"`
}

// SystemMessageAppendConfig is append mode: use CLI foundation with optional appended content.
type SystemMessageAppendConfig struct {
// Mode is optional, defaults to "append"
Expand All @@ -99,11 +120,15 @@ type SystemMessageReplaceConfig struct {
}

// SystemMessageConfig represents system message configuration for session creation.
// Use SystemMessageAppendConfig for default behavior, SystemMessageReplaceConfig for full control.
// In Go, use one struct or the other based on your needs.
// - Append mode (default): SDK foundation + optional custom content
// - Replace mode: Full control, caller provides entire system message
// - Customize mode: Section-level overrides with graceful fallback
//
// In Go, use one struct and set fields appropriate for the desired mode.
type SystemMessageConfig struct {
Mode string `json:"mode,omitempty"`
Content string `json:"content,omitempty"`
Mode string `json:"mode,omitempty"`
Content string `json:"content,omitempty"`
Sections map[string]SectionOverride `json:"sections,omitempty"`
}

// PermissionRequestResultKind represents the kind of a permission request result.
Expand Down
40 changes: 39 additions & 1 deletion nodejs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -443,7 +443,45 @@ const session = await client.createSession({
});
```

The SDK auto-injects environment context, tool instructions, and security guardrails. The default CLI persona is preserved, and your `content` is appended after SDK-managed sections. To change the persona or fully redefine the prompt, use `mode: "replace"`.
The SDK auto-injects environment context, tool instructions, and security guardrails. The default CLI persona is preserved, and your `content` is appended after SDK-managed sections. To change the persona or fully redefine the prompt, use `mode: "replace"` or `mode: "customize"`.

#### Customize Mode

Use `mode: "customize"` to selectively override individual sections of the prompt while preserving the rest:

```typescript
import { SYSTEM_PROMPT_SECTIONS } from "@anthropic-ai/sdk";
import type { SectionOverride, SystemPromptSection } from "@anthropic-ai/sdk";

const session = await client.createSession({
model: "gpt-5",
systemMessage: {
mode: "customize",
sections: {
// Replace the tone/style section
tone: { action: "replace", content: "Respond in a warm, professional tone. Be thorough in explanations." },
// Remove coding-specific rules
code_change_rules: { action: "remove" },
// Append to existing guidelines
guidelines: { action: "append", content: "\n* Always cite data sources" },
},
// Additional instructions appended after all sections
content: "Focus on financial analysis and reporting.",
},
});
```

Available section IDs: `identity`, `tone`, `tool_efficiency`, `environment_context`, `code_change_rules`, `guidelines`, `safety`, `tool_instructions`, `custom_instructions`. Use the `SYSTEM_PROMPT_SECTIONS` constant for descriptions of each section.

Each section override supports four actions:
- **`replace`** — Replace the section content entirely
- **`remove`** — Remove the section from the prompt
- **`append`** — Add content after the existing section
- **`prepend`** — Add content before the existing section

Unknown section IDs are handled gracefully: content from `replace`/`append`/`prepend` overrides is appended to additional instructions, and `remove` overrides are silently ignored.

#### Replace Mode

For full control (removes all guardrails), use `mode: "replace"`:

Expand Down
5 changes: 4 additions & 1 deletion nodejs/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

export { CopilotClient } from "./client.js";
export { CopilotSession, type AssistantMessageEvent } from "./session.js";
export { defineTool, approveAll } from "./types.js";
export { defineTool, approveAll, SYSTEM_PROMPT_SECTIONS } from "./types.js";
export type {
ConnectionState,
CopilotClientOptions,
Expand All @@ -31,6 +31,7 @@ export type {
PermissionRequest,
PermissionRequestResult,
ResumeSessionConfig,
SectionOverride,
SessionConfig,
SessionEvent,
SessionEventHandler,
Expand All @@ -44,7 +45,9 @@ export type {
SessionMetadata,
SystemMessageAppendConfig,
SystemMessageConfig,
SystemMessageCustomizeConfig,
SystemMessageReplaceConfig,
SystemPromptSection,
Tool,
ToolHandler,
ToolInvocation,
Expand Down
Loading
Loading