Skip to content

Commit 6c19fa2

Browse files
Merge branch 'main' into feat/mcp-apps-support
2 parents f61d1fe + 85d91ca commit 6c19fa2

14 files changed

Lines changed: 166 additions & 73 deletions

File tree

docs/getting-started.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1908,7 +1908,7 @@ const session = await client.createSession({
19081908
});
19091909
```
19101910

1911-
Available section IDs: `identity`, `tone`, `tool_efficiency`, `environment_context`, `code_change_rules`, `guidelines`, `safety`, `tool_instructions`, `custom_instructions`, `last_instructions`.
1911+
Available section IDs: `identity`, `tone`, `tool_efficiency`, `environment_context`, `code_change_rules`, `guidelines`, `safety`, `tool_instructions`, `custom_instructions`, `runtime_instructions`, `last_instructions`.
19121912

19131913
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.
19141914

dotnet/README.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copilot SDK
1+
# Copilot SDK
22

33
SDK for programmatic control of GitHub Copilot CLI.
44

@@ -627,18 +627,18 @@ var session = await client.CreateSessionAsync(new SessionConfig
627627
SystemMessage = new SystemMessageConfig
628628
{
629629
Mode = SystemMessageMode.Customize,
630-
Sections = new Dictionary<string, SectionOverride>
630+
Sections = new Dictionary<SystemMessageSection, SectionOverride>
631631
{
632-
[SystemPromptSections.Tone] = new() { Action = SectionOverrideAction.Replace, Content = "Respond in a warm, professional tone. Be thorough in explanations." },
633-
[SystemPromptSections.CodeChangeRules] = new() { Action = SectionOverrideAction.Remove },
634-
[SystemPromptSections.Guidelines] = new() { Action = SectionOverrideAction.Append, Content = "\n* Always cite data sources" },
632+
[SystemMessageSection.Tone] = new() { Action = SectionOverrideAction.Replace, Content = "Respond in a warm, professional tone. Be thorough in explanations." },
633+
[SystemMessageSection.CodeChangeRules] = new() { Action = SectionOverrideAction.Remove },
634+
[SystemMessageSection.Guidelines] = new() { Action = SectionOverrideAction.Append, Content = "\n* Always cite data sources" },
635635
},
636636
Content = "Focus on financial analysis and reporting."
637637
}
638638
});
639639
```
640640

641-
Available section IDs are defined as constants on `SystemPromptSections`: `Identity`, `Tone`, `ToolEfficiency`, `EnvironmentContext`, `CodeChangeRules`, `Guidelines`, `Safety`, `ToolInstructions`, `CustomInstructions`, `LastInstructions`.
641+
Available section IDs are defined as static properties on the `SystemMessageSection` struct: `Identity`, `Tone`, `ToolEfficiency`, `EnvironmentContext`, `CodeChangeRules`, `Guidelines`, `Safety`, `ToolInstructions`, `CustomInstructions`, `RuntimeInstructions`, `LastInstructions`.
642642

643643
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.
644644

dotnet/src/Client.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/*---------------------------------------------------------------------------------------------
1+
/*---------------------------------------------------------------------------------------------
22
* Copyright (c) Microsoft Corporation. All rights reserved.
33
*--------------------------------------------------------------------------------------------*/
44

@@ -464,13 +464,13 @@ private static (SystemMessageConfig? wireConfig, Dictionary<string, Func<string,
464464
}
465465

466466
var callbacks = new Dictionary<string, Func<string, Task<string>>>();
467-
var wireSections = new Dictionary<string, SectionOverride>();
467+
var wireSections = new Dictionary<SystemMessageSection, SectionOverride>();
468468

469469
foreach (var (sectionId, sectionOverride) in systemMessage.Sections)
470470
{
471471
if (sectionOverride.Transform != null)
472472
{
473-
callbacks[sectionId] = sectionOverride.Transform;
473+
callbacks[sectionId.Value] = sectionOverride.Transform;
474474
wireSections[sectionId] = new SectionOverride { Action = SectionOverrideAction.Transform };
475475
}
476476
else

dotnet/src/Types.cs

Lines changed: 82 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1757,7 +1757,7 @@ public enum SystemMessageMode
17571757
}
17581758

17591759
/// <summary>
1760-
/// Specifies the operation to perform on a system prompt section.
1760+
/// Specifies the operation to perform on a system message section.
17611761
/// </summary>
17621762
[JsonConverter(typeof(JsonStringEnumConverter<SectionOverrideAction>))]
17631763
public enum SectionOverrideAction
@@ -1780,7 +1780,7 @@ public enum SectionOverrideAction
17801780
}
17811781

17821782
/// <summary>
1783-
/// Override operation for a single system prompt section.
1783+
/// Override operation for a single system message section.
17841784
/// </summary>
17851785
public sealed class SectionOverride
17861786
{
@@ -1806,30 +1806,95 @@ public sealed class SectionOverride
18061806
}
18071807

18081808
/// <summary>
1809-
/// Known system prompt section identifiers for the "customize" mode.
1809+
/// Identifies a system message section for the "customize" mode.
18101810
/// </summary>
1811-
public static class SystemPromptSections
1811+
[JsonConverter(typeof(SystemMessageSection.Converter))]
1812+
public readonly struct SystemMessageSection : IEquatable<SystemMessageSection>
18121813
{
18131814
/// <summary>Agent identity preamble and mode statement.</summary>
1814-
public const string Identity = "identity";
1815+
public static SystemMessageSection Identity { get; } = new("identity");
18151816
/// <summary>Response style, conciseness rules, output formatting preferences.</summary>
1816-
public const string Tone = "tone";
1817+
public static SystemMessageSection Tone { get; } = new("tone");
18171818
/// <summary>Tool usage patterns, parallel calling, batching guidelines.</summary>
1818-
public const string ToolEfficiency = "tool_efficiency";
1819+
public static SystemMessageSection ToolEfficiency { get; } = new("tool_efficiency");
18191820
/// <summary>CWD, OS, git root, directory listing, available tools.</summary>
1820-
public const string EnvironmentContext = "environment_context";
1821+
public static SystemMessageSection EnvironmentContext { get; } = new("environment_context");
18211822
/// <summary>Coding rules, linting/testing, ecosystem tools, style.</summary>
1822-
public const string CodeChangeRules = "code_change_rules";
1823+
public static SystemMessageSection CodeChangeRules { get; } = new("code_change_rules");
18231824
/// <summary>Tips, behavioral best practices, behavioral guidelines.</summary>
1824-
public const string Guidelines = "guidelines";
1825+
public static SystemMessageSection Guidelines { get; } = new("guidelines");
18251826
/// <summary>Environment limitations, prohibited actions, security policies.</summary>
1826-
public const string Safety = "safety";
1827+
public static SystemMessageSection Safety { get; } = new("safety");
18271828
/// <summary>Per-tool usage instructions.</summary>
1828-
public const string ToolInstructions = "tool_instructions";
1829+
public static SystemMessageSection ToolInstructions { get; } = new("tool_instructions");
18291830
/// <summary>Repository and organization custom instructions.</summary>
1830-
public const string CustomInstructions = "custom_instructions";
1831+
public static SystemMessageSection CustomInstructions { get; } = new("custom_instructions");
1832+
/// <summary>Runtime-provided context and instructions (e.g. system notifications, memories, workspace context, mode-specific instructions, content-exclusion policy).</summary>
1833+
public static SystemMessageSection RuntimeInstructions { get; } = new("runtime_instructions");
18311834
/// <summary>End-of-prompt instructions: parallel tool calling, persistence, task completion.</summary>
1832-
public const string LastInstructions = "last_instructions";
1835+
public static SystemMessageSection LastInstructions { get; } = new("last_instructions");
1836+
1837+
/// <summary>Gets the underlying string value of this <see cref="SystemMessageSection"/>.</summary>
1838+
public string Value => _value ?? string.Empty;
1839+
1840+
private readonly string? _value;
1841+
1842+
/// <summary>Initializes a new instance of the <see cref="SystemMessageSection"/> struct.</summary>
1843+
/// <param name="value">The string value for this section identifier.</param>
1844+
[JsonConstructor]
1845+
public SystemMessageSection(string value) => _value = value;
1846+
1847+
/// <inheritdoc/>
1848+
public static bool operator ==(SystemMessageSection left, SystemMessageSection right) => left.Equals(right);
1849+
1850+
/// <inheritdoc/>
1851+
public static bool operator !=(SystemMessageSection left, SystemMessageSection right) => !left.Equals(right);
1852+
1853+
/// <inheritdoc/>
1854+
public override bool Equals([NotNullWhen(true)] object? obj) => obj is SystemMessageSection other && Equals(other);
1855+
1856+
/// <inheritdoc/>
1857+
public bool Equals(SystemMessageSection other) => string.Equals(Value, other.Value, StringComparison.OrdinalIgnoreCase);
1858+
1859+
/// <inheritdoc/>
1860+
public override int GetHashCode() => StringComparer.OrdinalIgnoreCase.GetHashCode(Value);
1861+
1862+
/// <inheritdoc/>
1863+
public override string ToString() => Value;
1864+
1865+
/// <summary>Provides a <see cref="JsonConverter{SystemMessageSection}"/> for serializing <see cref="SystemMessageSection"/> instances.</summary>
1866+
[EditorBrowsable(EditorBrowsableState.Never)]
1867+
public sealed class Converter : JsonConverter<SystemMessageSection>
1868+
{
1869+
/// <inheritdoc/>
1870+
public override SystemMessageSection Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
1871+
{
1872+
if (reader.TokenType != JsonTokenType.String)
1873+
{
1874+
throw new JsonException("Expected string for SystemMessageSection.");
1875+
}
1876+
1877+
var value = reader.GetString();
1878+
if (value is null)
1879+
{
1880+
throw new JsonException("SystemMessageSection value cannot be null.");
1881+
}
1882+
1883+
return new SystemMessageSection(value);
1884+
}
1885+
1886+
/// <inheritdoc/>
1887+
public override void Write(Utf8JsonWriter writer, SystemMessageSection value, JsonSerializerOptions options) =>
1888+
writer.WriteStringValue(value.Value);
1889+
1890+
/// <inheritdoc/>
1891+
public override SystemMessageSection ReadAsPropertyName(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) =>
1892+
new(reader.GetString()!);
1893+
1894+
/// <inheritdoc/>
1895+
public override void WriteAsPropertyName(Utf8JsonWriter writer, SystemMessageSection value, JsonSerializerOptions options) =>
1896+
writer.WritePropertyName(value.Value);
1897+
}
18331898
}
18341899

18351900
/// <summary>
@@ -1850,9 +1915,9 @@ public sealed class SystemMessageConfig
18501915

18511916
/// <summary>
18521917
/// Section-level overrides for customize mode.
1853-
/// Keys are section identifiers (see <see cref="SystemPromptSections"/>).
1918+
/// Keys are section identifiers (see <see cref="SystemMessageSection"/>).
18541919
/// </summary>
1855-
public IDictionary<string, SectionOverride>? Sections { get; set; }
1920+
public IDictionary<SystemMessageSection, SectionOverride>? Sections { get; set; }
18561921
}
18571922

18581923
/// <summary>
@@ -3035,7 +3100,7 @@ public sealed class SetForegroundSessionResponse
30353100
}
30363101

30373102
/// <summary>
3038-
/// Content data for a single system prompt section in a transform RPC call.
3103+
/// Content data for a single system message section in a transform RPC call.
30393104
/// </summary>
30403105
public sealed class SystemMessageTransformSection
30413106
{

dotnet/test/E2E/SessionE2ETests.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/*---------------------------------------------------------------------------------------------
1+
/*---------------------------------------------------------------------------------------------
22
* Copyright (c) Microsoft Corporation. All rights reserved.
33
*--------------------------------------------------------------------------------------------*/
44

@@ -101,10 +101,10 @@ public async Task Should_Create_A_Session_With_Customized_SystemMessage_Config()
101101
SystemMessage = new SystemMessageConfig
102102
{
103103
Mode = SystemMessageMode.Customize,
104-
Sections = new Dictionary<string, SectionOverride>
104+
Sections = new Dictionary<SystemMessageSection, SectionOverride>
105105
{
106-
[SystemPromptSections.Tone] = new() { Action = SectionOverrideAction.Replace, Content = customTone },
107-
[SystemPromptSections.CodeChangeRules] = new() { Action = SectionOverrideAction.Remove },
106+
[SystemMessageSection.Tone] = new() { Action = SectionOverrideAction.Replace, Content = customTone },
107+
[SystemMessageSection.CodeChangeRules] = new() { Action = SectionOverrideAction.Remove },
108108
},
109109
Content = appendedContent
110110
}

dotnet/test/E2E/SystemMessageTransformE2ETests.cs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@ public async Task Should_Invoke_Transform_Callbacks_With_Section_Content()
2222
SystemMessage = new SystemMessageConfig
2323
{
2424
Mode = SystemMessageMode.Customize,
25-
Sections = new Dictionary<string, SectionOverride>
25+
Sections = new Dictionary<SystemMessageSection, SectionOverride>
2626
{
27-
["identity"] = new SectionOverride
27+
[SystemMessageSection.Identity] = new SectionOverride
2828
{
2929
Transform = async (content) =>
3030
{
@@ -33,7 +33,7 @@ public async Task Should_Invoke_Transform_Callbacks_With_Section_Content()
3333
return content;
3434
}
3535
},
36-
["tone"] = new SectionOverride
36+
[SystemMessageSection.Tone] = new SectionOverride
3737
{
3838
Transform = async (content) =>
3939
{
@@ -68,9 +68,9 @@ public async Task Should_Apply_Transform_Modifications_To_Section_Content()
6868
SystemMessage = new SystemMessageConfig
6969
{
7070
Mode = SystemMessageMode.Customize,
71-
Sections = new Dictionary<string, SectionOverride>
71+
Sections = new Dictionary<SystemMessageSection, SectionOverride>
7272
{
73-
["identity"] = new SectionOverride
73+
[SystemMessageSection.Identity] = new SectionOverride
7474
{
7575
Transform = async (content) =>
7676
{
@@ -108,13 +108,13 @@ public async Task Should_Work_With_Static_Overrides_And_Transforms_Together()
108108
SystemMessage = new SystemMessageConfig
109109
{
110110
Mode = SystemMessageMode.Customize,
111-
Sections = new Dictionary<string, SectionOverride>
111+
Sections = new Dictionary<SystemMessageSection, SectionOverride>
112112
{
113-
["safety"] = new SectionOverride
113+
[SystemMessageSection.Safety] = new SectionOverride
114114
{
115115
Action = SectionOverrideAction.Remove
116116
},
117-
["identity"] = new SectionOverride
117+
[SystemMessageSection.Identity] = new SectionOverride
118118
{
119119
Transform = async (content) =>
120120
{

dotnet/test/Unit/PublicDtoTests.cs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -174,15 +174,17 @@ private static bool TryCreateGenericCollection(Type type, HashSet<Type> visited,
174174
.FirstOrDefault(candidate =>
175175
candidate.IsGenericType &&
176176
(candidate.GetGenericTypeDefinition() == typeof(IDictionary<,>) ||
177-
candidate.GetGenericTypeDefinition() == typeof(IReadOnlyDictionary<,>)) &&
178-
candidate.GetGenericArguments()[0] == typeof(string));
177+
candidate.GetGenericTypeDefinition() == typeof(IReadOnlyDictionary<,>)));
179178

180179
if (dictionaryInterface is not null)
181180
{
181+
var keyType = dictionaryInterface.GetGenericArguments()[0];
182182
var valueType = dictionaryInterface.GetGenericArguments()[1];
183+
TryCreateSampleValue(keyType, visited, out var sampleKey);
183184
TryCreateSampleValue(valueType, visited, out var sampleValue);
184-
var dictionary = (IDictionary)Activator.CreateInstance(typeof(Dictionary<,>).MakeGenericType(typeof(string), valueType))!;
185-
dictionary["key"] = sampleValue;
185+
var dictionaryType = typeof(Dictionary<,>).MakeGenericType(keyType, valueType);
186+
var dictionary = (IDictionary)Activator.CreateInstance(dictionaryType)!;
187+
dictionary[sampleKey!] = sampleValue;
186188
value = dictionary;
187189
return true;
188190
}

go/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ Event types: `SessionLifecycleCreated`, `SessionLifecycleDeleted`, `SessionLifec
160160
- `SystemMessage` (\*SystemMessageConfig): System message configuration. Supports three modes:
161161
- **append** (default): Appends `Content` after the SDK-managed prompt
162162
- **replace**: Replaces the entire prompt with `Content`
163-
- **customize**: Selectively override individual sections via `Sections` map (keys: `SectionIdentity`, `SectionTone`, `SectionToolEfficiency`, `SectionEnvironmentContext`, `SectionCodeChangeRules`, `SectionGuidelines`, `SectionSafety`, `SectionToolInstructions`, `SectionCustomInstructions`, `SectionLastInstructions`; values: `SectionOverride` with `Action` and optional `Content`)
163+
- **customize**: Selectively override individual sections via `Sections` map (keys: `SectionIdentity`, `SectionTone`, `SectionToolEfficiency`, `SectionEnvironmentContext`, `SectionCodeChangeRules`, `SectionGuidelines`, `SectionSafety`, `SectionToolInstructions`, `SectionCustomInstructions`, `SectionRuntimeInstructions`, `SectionLastInstructions`; values: `SectionOverride` with `Action` and optional `Content`)
164164
- `Provider` (\*ProviderConfig): Custom API provider configuration (BYOK). See [Custom Providers](#custom-providers) section.
165165
- `Streaming` (*bool): Enable streaming delta events (nil = runtime default)
166166
- `InfiniteSessions` (\*InfiniteSessionConfig): Automatic context compaction configuration
@@ -233,7 +233,7 @@ session, err := client.CreateSession(ctx, &copilot.SessionConfig{
233233
})
234234
```
235235

236-
Available section constants: `SectionIdentity`, `SectionTone`, `SectionToolEfficiency`, `SectionEnvironmentContext`, `SectionCodeChangeRules`, `SectionGuidelines`, `SectionSafety`, `SectionToolInstructions`, `SectionCustomInstructions`, `SectionLastInstructions`.
236+
Available section constants: `SectionIdentity`, `SectionTone`, `SectionToolEfficiency`, `SectionEnvironmentContext`, `SectionCodeChangeRules`, `SectionGuidelines`, `SectionSafety`, `SectionToolInstructions`, `SectionCustomInstructions`, `SectionRuntimeInstructions`, `SectionLastInstructions`.
237237

238238
Each section override supports four actions:
239239

0 commit comments

Comments
 (0)