Skip to content

Commit 793eb03

Browse files
Copilotstephentoub
andauthored
Add deprecation message to [Obsolete] attributes in C# generator
Agent-Logs-Url: https://github.com/github/copilot-sdk/sessions/35a08e5f-ea8a-4494-9e24-084aad8ec639 Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com>
1 parent 0af6ab8 commit 793eb03

3 files changed

Lines changed: 20 additions & 75 deletions

File tree

dotnet/src/Generated/SessionEvents.cs

Lines changed: 5 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

scripts/codegen/csharp.ts

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,7 @@ function getOrCreateEnum(parentClassName: string, propName: string, values: stri
326326

327327
const lines: string[] = [];
328328
lines.push(...xmlDocEnumComment(description, ""));
329-
if (deprecated) lines.push(`[Obsolete]`);
329+
if (deprecated) lines.push(`[Obsolete("This member is deprecated and will be removed in a future version.")]`);
330330
lines.push(`[JsonConverter(typeof(JsonStringEnumConverter<${enumName}>))]`, `public enum ${enumName}`, `{`);
331331
for (const value of values) {
332332
lines.push(` /// <summary>The <c>${escapeXml(value)}</c> variant.</summary>`);
@@ -461,7 +461,7 @@ function generateDerivedClass(
461461
const required = new Set(schema.required || []);
462462

463463
lines.push(...xmlDocCommentWithFallback(schema.description, `The <c>${escapeXml(discriminatorValue)}</c> variant of <see cref="${baseClassName}"/>.`, ""));
464-
if (isSchemaDeprecated(schema)) lines.push(`[Obsolete]`);
464+
if (isSchemaDeprecated(schema)) lines.push(`[Obsolete("This member is deprecated and will be removed in a future version.")]`);
465465
lines.push(`public partial class ${className} : ${baseClassName}`);
466466
lines.push(`{`);
467467
lines.push(` /// <inheritdoc />`);
@@ -480,7 +480,7 @@ function generateDerivedClass(
480480

481481
lines.push(...xmlDocPropertyComment((propSchema as JSONSchema7).description, propName, " "));
482482
lines.push(...emitDataAnnotations(propSchema as JSONSchema7, " "));
483-
if (isSchemaDeprecated(propSchema as JSONSchema7)) lines.push(` [Obsolete]`);
483+
if (isSchemaDeprecated(propSchema as JSONSchema7)) lines.push(` [Obsolete("This member is deprecated and will be removed in a future version.")]`);
484484
if (isDurationProperty(propSchema as JSONSchema7)) lines.push(` [JsonConverter(typeof(MillisecondsTimeSpanConverter))]`);
485485
if (!isReq) lines.push(` [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]`);
486486
lines.push(` [JsonPropertyName("${propName}")]`);
@@ -504,7 +504,7 @@ function generateNestedClass(
504504
const required = new Set(schema.required || []);
505505
const lines: string[] = [];
506506
lines.push(...xmlDocCommentWithFallback(schema.description, `Nested data type for <c>${className}</c>.`, ""));
507-
if (isSchemaDeprecated(schema)) lines.push(`[Obsolete]`);
507+
if (isSchemaDeprecated(schema)) lines.push(`[Obsolete("This member is deprecated and will be removed in a future version.")]`);
508508
lines.push(`public partial class ${className}`, `{`);
509509

510510
for (const [propName, propSchema] of Object.entries(schema.properties || {})) {
@@ -516,7 +516,7 @@ function generateNestedClass(
516516

517517
lines.push(...xmlDocPropertyComment(prop.description, propName, " "));
518518
lines.push(...emitDataAnnotations(prop, " "));
519-
if (isSchemaDeprecated(prop)) lines.push(` [Obsolete]`);
519+
if (isSchemaDeprecated(prop)) lines.push(` [Obsolete("This member is deprecated and will be removed in a future version.")]`);
520520
if (isDurationProperty(prop)) lines.push(` [JsonConverter(typeof(MillisecondsTimeSpanConverter))]`);
521521
if (!isReq) lines.push(` [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]`);
522522
lines.push(` [JsonPropertyName("${propName}")]`);
@@ -615,7 +615,7 @@ function generateDataClass(variant: EventVariant, knownTypes: Map<string, string
615615
lines.push(...rawXmlDocSummary(`Event payload for <see cref="${variant.className}"/>.`, ""));
616616
}
617617
if (isSchemaDeprecated(variant.dataSchema)) {
618-
lines.push(`[Obsolete]`);
618+
lines.push(`[Obsolete("This member is deprecated and will be removed in a future version.")]`);
619619
}
620620
lines.push(`public partial class ${variant.dataClassName}`, `{`);
621621

@@ -627,7 +627,7 @@ function generateDataClass(variant: EventVariant, knownTypes: Map<string, string
627627

628628
lines.push(...xmlDocPropertyComment((propSchema as JSONSchema7).description, propName, " "));
629629
lines.push(...emitDataAnnotations(propSchema as JSONSchema7, " "));
630-
if (isSchemaDeprecated(propSchema as JSONSchema7)) lines.push(` [Obsolete]`);
630+
if (isSchemaDeprecated(propSchema as JSONSchema7)) lines.push(` [Obsolete("This member is deprecated and will be removed in a future version.")]`);
631631
if (isDurationProperty(propSchema as JSONSchema7)) lines.push(` [JsonConverter(typeof(MillisecondsTimeSpanConverter))]`);
632632
if (!isReq) lines.push(` [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]`);
633633
lines.push(` [JsonPropertyName("${propName}")]`);
@@ -906,7 +906,7 @@ function emitRpcClass(
906906
lines.push(`[Experimental(Diagnostics.Experimental)]`);
907907
}
908908
if (isSchemaDeprecated(schema) || isSchemaDeprecated(effectiveSchema)) {
909-
lines.push(`[Obsolete]`);
909+
lines.push(`[Obsolete("This member is deprecated and will be removed in a future version.")]`);
910910
}
911911
lines.push(`${visibility} sealed class ${className}`, `{`);
912912

@@ -921,7 +921,7 @@ function emitRpcClass(
921921

922922
lines.push(...xmlDocPropertyComment(prop.description, propName, " "));
923923
lines.push(...emitDataAnnotations(prop, " "));
924-
if (isSchemaDeprecated(prop)) lines.push(` [Obsolete]`);
924+
if (isSchemaDeprecated(prop)) lines.push(` [Obsolete("This member is deprecated and will be removed in a future version.")]`);
925925
if (isDurationProperty(prop)) lines.push(` [JsonConverter(typeof(MillisecondsTimeSpanConverter))]`);
926926
lines.push(` [JsonPropertyName("${propName}")]`);
927927

@@ -1024,7 +1024,7 @@ function emitServerApiClass(className: string, node: Record<string, unknown>, cl
10241024
lines.push(`[Experimental(Diagnostics.Experimental)]`);
10251025
}
10261026
if (groupDeprecated) {
1027-
lines.push(`[Obsolete]`);
1027+
lines.push(`[Obsolete("This member is deprecated and will be removed in a future version.")]`);
10281028
}
10291029
lines.push(`public sealed class ${className}`);
10301030
lines.push(`{`);
@@ -1104,7 +1104,7 @@ function emitServerInstanceMethod(
11041104
lines.push(`${indent}[Experimental(Diagnostics.Experimental)]`);
11051105
}
11061106
if (method.deprecated && !groupDeprecated) {
1107-
lines.push(`${indent}[Obsolete]`);
1107+
lines.push(`${indent}[Obsolete("This member is deprecated and will be removed in a future version.")]`);
11081108
}
11091109

11101110
const sigParams: string[] = [];
@@ -1208,7 +1208,7 @@ function emitSessionMethod(key: string, method: RpcMethod, lines: string[], clas
12081208
lines.push(`${indent}[Experimental(Diagnostics.Experimental)]`);
12091209
}
12101210
if (method.deprecated && !groupDeprecated) {
1211-
lines.push(`${indent}[Obsolete]`);
1211+
lines.push(`${indent}[Obsolete("This member is deprecated and will be removed in a future version.")]`);
12121212
}
12131213
const sigParams: string[] = [];
12141214
const bodyAssignments = [`SessionId = _sessionId`];
@@ -1238,7 +1238,7 @@ function emitSessionApiClass(className: string, node: Record<string, unknown>, c
12381238
const groupExperimental = isNodeFullyExperimental(node);
12391239
const groupDeprecated = isNodeFullyDeprecated(node);
12401240
const experimentalAttr = groupExperimental ? `[Experimental(Diagnostics.Experimental)]\n` : "";
1241-
const deprecatedAttr = groupDeprecated ? `[Obsolete]\n` : "";
1241+
const deprecatedAttr = groupDeprecated ? `[Obsolete("This member is deprecated and will be removed in a future version.")]\n` : "";
12421242
const subGroups = Object.entries(node).filter(([, v]) => typeof v === "object" && v !== null && !isRpcMethod(v));
12431243

12441244
const lines = [`/// <summary>Provides session-scoped ${displayName} APIs.</summary>`, `${experimentalAttr}${deprecatedAttr}public sealed class ${className}`, `{`, ` private readonly JsonRpc _rpc;`, ` private readonly string _sessionId;`, ""];
@@ -1328,7 +1328,7 @@ function emitClientSessionApiRegistration(clientSchema: Record<string, unknown>,
13281328
lines.push(`[Experimental(Diagnostics.Experimental)]`);
13291329
}
13301330
if (groupDeprecated) {
1331-
lines.push(`[Obsolete]`);
1331+
lines.push(`[Obsolete("This member is deprecated and will be removed in a future version.")]`);
13321332
}
13331333
lines.push(`public interface ${interfaceName}`);
13341334
lines.push(`{`);
@@ -1342,7 +1342,7 @@ function emitClientSessionApiRegistration(clientSchema: Record<string, unknown>,
13421342
lines.push(` [Experimental(Diagnostics.Experimental)]`);
13431343
}
13441344
if (method.deprecated && !groupDeprecated) {
1345-
lines.push(` [Obsolete]`);
1345+
lines.push(` [Obsolete("This member is deprecated and will be removed in a future version.")]`);
13461346
}
13471347
if (hasParams) {
13481348
lines.push(` ${taskType} ${clientHandlerMethodName(method.rpcMethod)}(${paramsTypeName(method)} request, CancellationToken cancellationToken = default);`);

test/snapshots/session_config/vision_disabled_then_enabled_via_setmodel.yaml

Lines changed: 0 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -63,58 +63,3 @@ conversations:
6363
function:
6464
name: view
6565
arguments: '{"path":"${workdir}/test.png"}'
66-
- messages:
67-
- role: system
68-
content: ${system}
69-
- role: user
70-
content: Use the view tool to look at the file test.png and describe what you see
71-
- role: assistant
72-
tool_calls:
73-
- id: toolcall_0
74-
type: function
75-
function:
76-
name: report_intent
77-
arguments: '{"intent":"Viewing image file"}'
78-
- id: toolcall_1
79-
type: function
80-
function:
81-
name: view
82-
arguments: '{"path":"${workdir}/test.png"}'
83-
- role: tool
84-
tool_call_id: toolcall_0
85-
content: Intent logged
86-
- role: tool
87-
tool_call_id: toolcall_1
88-
content: Viewed image file successfully.
89-
- role: assistant
90-
content: The image shows a **GitHub Copilot logo** - a hexagonal icon with an orange/coral colored background containing
91-
a stylized white design that represents the Copilot brand mark. The logo has the characteristic GitHub Copilot
92-
appearance with its geometric hexagon shape and minimal design aesthetic.
93-
- role: user
94-
content: Use the view tool to look at the file test.png and describe what you see
95-
- role: assistant
96-
tool_calls:
97-
- id: toolcall_2
98-
type: function
99-
function:
100-
name: report_intent
101-
arguments: '{"intent":"Viewing image file"}'
102-
- id: toolcall_3
103-
type: function
104-
function:
105-
name: view
106-
arguments: '{"path":"${workdir}/test.png"}'
107-
- role: tool
108-
tool_call_id: toolcall_2
109-
content: Intent logged
110-
- role: tool
111-
tool_call_id: toolcall_3
112-
content: Viewed image file successfully.
113-
- role: user
114-
content: |-
115-
Image file at path ${workdir}/test.png
116-
[image]
117-
- role: assistant
118-
content: The image appears to be a **very small, mostly blank white or off-white rectangular image**. There doesn't seem
119-
to be any visible content, text, or graphics - just a plain light-colored background. It looks like either an
120-
empty/blank image file or a very minimalistic placeholder image.

0 commit comments

Comments
 (0)