Skip to content

Commit 040530f

Browse files
Use application terminology for client info (#2482)
* Rename client info fields for applications Use application and integration terminology in every public SDK while preserving the existing runtime wire protocol. Update tests and documentation to match. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Apply Java source formatting Match the repository's Spotless line wrapping for the updated client identity documentation. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Clarify client info examples Keep the IDE example across languages, document application-only usage, and explain integrations as optional extensions, plugins, or other application sub-parts. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Clarify integration field documentation Describe integration identity consistently across all six SDKs as an optional application extension, plugin, or other named sub-part. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Apply Java comment formatting Match Spotless wrapping for the clarified integration accessor documentation. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent aae1462 commit 040530f

20 files changed

Lines changed: 318 additions & 301 deletions

File tree

CHANGELOG.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ See [GitHub Releases](https://github.com/github/copilot-sdk/releases) for the fu
77

88
## [Unreleased]
99

10-
### Feature: declare host identity with client info
10+
### Feature: declare application identity with client info
1111

12-
Client options now accept optional client info (editor name and version, extension name and version) across all six SDKs, exposed idiomatically per language (`clientInfo` in Node.js, `client_info` in Python and Rust, `ClientInfo` in Go and .NET, `setClientInfo` in Java). When set, the SDK forwards it on the `server.connect` handshake so the telemetry the runtime emits on the connection is attributed to the host editor and its Copilot extension instead of the runtime's own build. All fields are optional, and leaving client info unset keeps the runtime's default attribution. See [Client info](./docs/features/client-info.md).
12+
Client options now accept optional client info (application name and version, integration name and version) across all six SDKs, exposed idiomatically per language (`clientInfo` in Node.js, `client_info` in Python and Rust, `ClientInfo` in Go and .NET, `setClientInfo` in Java). When set, the SDK forwards it on the `server.connect` handshake so the telemetry the runtime emits on the connection is attributed to the application and its Copilot integration instead of the runtime's own build. All fields are optional, and leaving client info unset keeps the runtime's default attribution. See [Client info](./docs/features/client-info.md).
1313

1414
### Feature: Node Agent Factories pagination and run notifications
1515

docs/features/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ These guides cover the capabilities you can add to your Copilot SDK application.
2020
| [Image Input](./image-input.md) | Send images to sessions as attachments |
2121
| [Streaming Events](./streaming-events.md) | Subscribe to real-time session events (40+ event types) |
2222
| [Usage and Billing](./usage-and-billing.md) | Read token counts, context-window utilization, AI credit cost, and account quota |
23-
| [Client info](./client-info.md) | Declare the host editor and extension so runtime telemetry is attributed to your surface |
23+
| [Client info](./client-info.md) | Declare application and integration identity for runtime telemetry attribution |
2424
| [Steering & Queueing](./steering-and-queueing.md) | Control message delivery—immediate steering vs. sequential queueing |
2525
| [Context Clearing](./context-management.md) | Replace conversation context safely with terminal tools |
2626
| [Session Persistence](./session-persistence.md) | Resume sessions across restarts, manage session storage |

docs/features/client-info.md

Lines changed: 49 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,23 @@
11
# Client info
22

3-
Client info identifies the editor or extension that hosts your Copilot SDK application. Set the optional `clientInfo` client option to attribute runtime telemetry for that connection to your host instead of the runtime's own build.
3+
Client info identifies the application using the Copilot SDK and, when applicable, a specific integration within it. An integration is an identifiable sub-part of the application through which the SDK is used, such as an extension or plugin. Set the optional `clientInfo` client option to attribute runtime telemetry for that connection to your application instead of the runtime's own build.
44

55
## When to set client info
66

7-
Set client info when you embed the SDK in an editor, an extension, or another application with its own identity.
7+
Set client info when your SDK application represents a distinct product, service, or integration whose runtime activity should be attributed consistently.
88

9-
Leave client info unset for scripts, one-off tools, and back-end jobs that do not represent a distinct host. The runtime then keeps its default attribution.
9+
Leave client info unset for scripts, one-off tools, and jobs that do not represent a distinct application. The runtime then keeps its default attribution.
1010

1111
Client info has four optional string fields. Set the fields you know and omit the rest. The SDK includes client info in the `server.connect` handshake only when at least one field has a non-empty value.
1212

1313
| Field | Example | Meaning |
1414
|---|---|---|
15-
| `editorName` | `"vscode"` | Name of the host editor |
16-
| `editorVersion` | `"1.124.2"` | Version of the host editor |
17-
| `extensionName` | `"copilot-chat"` | Name of the Copilot extension within the host |
18-
| `extensionVersion` | `"0.54.0"` | Version of the Copilot extension within the host |
15+
| `applicationName` | `"vscode"` | Name of the application using the SDK |
16+
| `applicationVersion` | `"1.124.2"` | Version of the application using the SDK |
17+
| `integrationName` | `"copilot-chat"` | Name of the extension, plugin, or other application sub-part using the SDK |
18+
| `integrationVersion` | `"0.54.0"` | Version of that extension, plugin, or application sub-part |
19+
20+
For a standalone application without a distinct integration, set only the application fields. For example, a developer portal could set `applicationName` to `"acme-developer-portal"` and `applicationVersion` to `"2.4.0"`, leaving both integration fields unset.
1921

2022
The SDK sends client info once when it establishes the connection. The identity applies for the lifetime of that connection.
2123

@@ -33,10 +35,10 @@ import { CopilotClient } from "@github/copilot-sdk";
3335
async function main() {
3436
const client = new CopilotClient({
3537
clientInfo: {
36-
editorName: "JetBrains-IU",
37-
editorVersion: "2026.1",
38-
extensionName: "copilot-intellij",
39-
extensionVersion: "1.5.0",
38+
applicationName: "vscode",
39+
applicationVersion: "1.124.2",
40+
integrationName: "copilot-chat",
41+
integrationVersion: "0.54.0",
4042
},
4143
});
4244

@@ -52,10 +54,10 @@ import { CopilotClient } from "@github/copilot-sdk";
5254

5355
const client = new CopilotClient({
5456
clientInfo: {
55-
editorName: "JetBrains-IU",
56-
editorVersion: "2026.1",
57-
extensionName: "copilot-intellij",
58-
extensionVersion: "1.5.0",
57+
applicationName: "vscode",
58+
applicationVersion: "1.124.2",
59+
integrationName: "copilot-chat",
60+
integrationVersion: "0.54.0",
5961
},
6062
});
6163

@@ -73,10 +75,10 @@ from copilot import CopilotClient
7375

7476
client = CopilotClient(
7577
client_info={
76-
"editor_name": "JetBrains-IU",
77-
"editor_version": "2026.1",
78-
"extension_name": "copilot-intellij",
79-
"extension_version": "1.5.0",
78+
"application_name": "vscode",
79+
"application_version": "1.124.2",
80+
"integration_name": "copilot-chat",
81+
"integration_version": "0.54.0",
8082
},
8183
)
8284
await client.start()
@@ -101,10 +103,10 @@ func main() {
101103
ctx := context.Background()
102104
client := copilot.NewClient(&copilot.ClientOptions{
103105
ClientInfo: &copilot.ClientInfo{
104-
EditorName: "JetBrains-IU",
105-
EditorVersion: "2026.1",
106-
ExtensionName: "copilot-intellij",
107-
ExtensionVersion: "1.5.0",
106+
ApplicationName: "vscode",
107+
ApplicationVersion: "1.124.2",
108+
IntegrationName: "copilot-chat",
109+
IntegrationVersion: "0.54.0",
108110
},
109111
})
110112
if err := client.Start(ctx); err != nil {
@@ -117,10 +119,10 @@ func main() {
117119
```go
118120
client := copilot.NewClient(&copilot.ClientOptions{
119121
ClientInfo: &copilot.ClientInfo{
120-
EditorName: "JetBrains-IU",
121-
EditorVersion: "2026.1",
122-
ExtensionName: "copilot-intellij",
123-
ExtensionVersion: "1.5.0",
122+
ApplicationName: "vscode",
123+
ApplicationVersion: "1.124.2",
124+
IntegrationName: "copilot-chat",
125+
IntegrationVersion: "0.54.0",
124126
},
125127
})
126128
if err := client.Start(ctx); err != nil {
@@ -140,10 +142,10 @@ await using var client = new CopilotClient(new CopilotClientOptions
140142
{
141143
ClientInfo = new CopilotClientInfo
142144
{
143-
EditorName = "JetBrains-IU",
144-
EditorVersion = "2026.1",
145-
ExtensionName = "copilot-intellij",
146-
ExtensionVersion = "1.5.0",
145+
ApplicationName = "vscode",
146+
ApplicationVersion = "1.124.2",
147+
IntegrationName = "copilot-chat",
148+
IntegrationVersion = "0.54.0",
147149
},
148150
});
149151

@@ -165,10 +167,10 @@ public class ClientInfoExample {
165167
public static void main(String[] args) throws Exception {
166168
var options = new CopilotClientOptions()
167169
.setClientInfo(new ClientInfo()
168-
.setEditorName("JetBrains-IU")
169-
.setEditorVersion("2026.1")
170-
.setExtensionName("copilot-intellij")
171-
.setExtensionVersion("1.5.0"));
170+
.setApplicationName("vscode")
171+
.setApplicationVersion("1.124.2")
172+
.setIntegrationName("copilot-chat")
173+
.setIntegrationVersion("0.54.0"));
172174

173175
var client = new CopilotClient(options);
174176
client.start().get();
@@ -180,10 +182,10 @@ public class ClientInfoExample {
180182
```java
181183
var options = new CopilotClientOptions()
182184
.setClientInfo(new ClientInfo()
183-
.setEditorName("JetBrains-IU")
184-
.setEditorVersion("2026.1")
185-
.setExtensionName("copilot-intellij")
186-
.setExtensionVersion("1.5.0"));
185+
.setApplicationName("vscode")
186+
.setApplicationVersion("1.124.2")
187+
.setIntegrationName("copilot-chat")
188+
.setIntegrationVersion("0.54.0"));
187189

188190
var client = new CopilotClient(options);
189191
client.start().get();
@@ -203,10 +205,10 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
203205
let _client = Client::start(
204206
ClientOptions::new().with_client_info(
205207
ClientInfo::new()
206-
.with_editor_name("JetBrains-IU")
207-
.with_editor_version("2026.1")
208-
.with_extension_name("copilot-intellij")
209-
.with_extension_version("1.5.0"),
208+
.with_application_name("vscode")
209+
.with_application_version("1.124.2")
210+
.with_integration_name("copilot-chat")
211+
.with_integration_version("0.54.0"),
210212
),
211213
)
212214
.await?;
@@ -221,10 +223,10 @@ use github_copilot_sdk::{Client, ClientInfo, ClientOptions};
221223
let client = Client::start(
222224
ClientOptions::new().with_client_info(
223225
ClientInfo::new()
224-
.with_editor_name("JetBrains-IU")
225-
.with_editor_version("2026.1")
226-
.with_extension_name("copilot-intellij")
227-
.with_extension_version("1.5.0"),
226+
.with_application_name("vscode")
227+
.with_application_version("1.124.2")
228+
.with_integration_name("copilot-chat")
229+
.with_integration_version("0.54.0"),
228230
),
229231
)
230232
.await?;

dotnet/src/Client.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2183,7 +2183,7 @@ [new ConnectHandshakeRequest(
21832183
// `connect` handshake so the first session's un-replayable `session.start`
21842184
// event is forwarded). Also sent on session.create/resume for older CLIs.
21852185
_options.OnGitHubTelemetry != null ? true : null,
2186-
// Declare the integrating host's identity so the runtime attributes the
2186+
// Declare the integrating application's identity so the runtime attributes the
21872187
// telemetry it emits on this connection to a consistent surface instead
21882188
// of its own build. Null when the app didn't supply it.
21892189
ConnectHandshakeClientInfo.From(_options.ClientInfo))],
@@ -3213,10 +3213,10 @@ internal record ConnectHandshakeClientInfo(
32133213
return null;
32143214
}
32153215

3216-
var editorName = NullIfEmpty(info.EditorName);
3217-
var editorVersion = NullIfEmpty(info.EditorVersion);
3218-
var extensionName = NullIfEmpty(info.ExtensionName);
3219-
var extensionVersion = NullIfEmpty(info.ExtensionVersion);
3216+
var editorName = NullIfEmpty(info.ApplicationName);
3217+
var editorVersion = NullIfEmpty(info.ApplicationVersion);
3218+
var extensionName = NullIfEmpty(info.IntegrationName);
3219+
var extensionVersion = NullIfEmpty(info.IntegrationVersion);
32203220
if (editorName is null && editorVersion is null && extensionName is null && extensionVersion is null)
32213221
{
32223222
return null;

dotnet/src/Types.cs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -467,10 +467,10 @@ private CopilotClientOptions(CopilotClientOptions? other)
467467
public bool EnableRemoteSessions { get; set; }
468468

469469
/// <summary>
470-
/// Declares the integrating host's identity, forwarded to the runtime on the
470+
/// Declares the integrating application's identity, forwarded to the runtime on the
471471
/// <c>server.connect</c> handshake. Declaring it lets the telemetry the
472472
/// runtime emits on this connection be attributed to a consistent surface
473-
/// (the host editor and its Copilot extension) instead of the runtime's own
473+
/// (the application and its Copilot integration) instead of the runtime's own
474474
/// build. All fields are optional; leave it <see langword="null"/> to keep
475475
/// the runtime's default attribution.
476476
/// </summary>
@@ -543,7 +543,7 @@ public sealed class TelemetryConfig
543543
}
544544

545545
/// <summary>
546-
/// Identifies the integrating host on the <c>server.connect</c> handshake.
546+
/// Identifies the integrating application on the <c>server.connect</c> handshake.
547547
/// </summary>
548548
/// <remarks>
549549
/// Declaring it lets the telemetry the runtime emits on the connection be
@@ -554,24 +554,24 @@ public sealed class TelemetryConfig
554554
public sealed class CopilotClientInfo
555555
{
556556
/// <summary>
557-
/// Name of the host editor, e.g. <c>"vscode"</c>.
557+
/// Name of the application using the SDK.
558558
/// </summary>
559-
public string? EditorName { get; set; }
559+
public string? ApplicationName { get; set; }
560560

561561
/// <summary>
562-
/// Version of the host editor, e.g. <c>"1.124.2"</c>.
562+
/// Version of the application using the SDK.
563563
/// </summary>
564-
public string? EditorVersion { get; set; }
564+
public string? ApplicationVersion { get; set; }
565565

566566
/// <summary>
567-
/// Name of the Copilot extension within the host, e.g. <c>"copilot-chat"</c>.
567+
/// Optionally specifies a named integration within the application, such as an extension or plugin.
568568
/// </summary>
569-
public string? ExtensionName { get; set; }
569+
public string? IntegrationName { get; set; }
570570

571571
/// <summary>
572-
/// Version of the Copilot extension within the host, e.g. <c>"0.54.0"</c>.
572+
/// Optionally specifies the version of that integration.
573573
/// </summary>
574-
public string? ExtensionVersion { get; set; }
574+
public string? IntegrationVersion { get; set; }
575575
}
576576

577577
/// <summary>

dotnet/test/Unit/CloneTests.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,10 @@ public void CopilotClientOptions_Clone_CopiesAllProperties()
2525
SessionIdleTimeoutSeconds = 600,
2626
ClientInfo = new CopilotClientInfo
2727
{
28-
EditorName = "example-editor",
29-
EditorVersion = "1.0.0",
30-
ExtensionName = "example-extension",
31-
ExtensionVersion = "2.0.0",
28+
ApplicationName = "example-app",
29+
ApplicationVersion = "1.0.0",
30+
IntegrationName = "example-integration",
31+
IntegrationVersion = "2.0.0",
3232
},
3333
};
3434

dotnet/test/Unit/GitHubTelemetryTests.cs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -149,19 +149,19 @@ public async Task Connect_Forwards_Declared_ClientInfo()
149149
Connection = RuntimeConnection.ForUri(server.Url),
150150
ClientInfo = new CopilotClientInfo
151151
{
152-
EditorName = "JetBrains-IU",
153-
EditorVersion = "2026.1",
154-
ExtensionName = "copilot-intellij",
155-
ExtensionVersion = "1.5.0",
152+
ApplicationName = "acme-developer-portal",
153+
ApplicationVersion = "2.4.0",
154+
IntegrationName = "copilot-assistant",
155+
IntegrationVersion = "1.5.0",
156156
},
157157
});
158158
await client.StartAsync();
159159

160160
var connectParams = server.LastConnectParams ?? throw new InvalidOperationException("connect was not captured.");
161161
Assert.True(connectParams.TryGetProperty("clientInfo", out var clientInfo));
162-
Assert.Equal("JetBrains-IU", clientInfo.GetProperty("editorName").GetString());
163-
Assert.Equal("2026.1", clientInfo.GetProperty("editorVersion").GetString());
164-
Assert.Equal("copilot-intellij", clientInfo.GetProperty("extensionName").GetString());
162+
Assert.Equal("acme-developer-portal", clientInfo.GetProperty("editorName").GetString());
163+
Assert.Equal("2.4.0", clientInfo.GetProperty("editorVersion").GetString());
164+
Assert.Equal("copilot-assistant", clientInfo.GetProperty("extensionName").GetString());
165165
Assert.Equal("1.5.0", clientInfo.GetProperty("extensionVersion").GetString());
166166
}
167167

@@ -188,13 +188,13 @@ public async Task Connect_Omits_Empty_ClientInfo_Fields()
188188
await using var client = new CopilotClient(new CopilotClientOptions
189189
{
190190
Connection = RuntimeConnection.ForUri(server.Url),
191-
ClientInfo = new CopilotClientInfo { EditorName = "example-editor", EditorVersion = "" },
191+
ClientInfo = new CopilotClientInfo { ApplicationName = "example-app", ApplicationVersion = "" },
192192
});
193193
await client.StartAsync();
194194

195195
var connectParams = server.LastConnectParams ?? throw new InvalidOperationException("connect was not captured.");
196196
Assert.True(connectParams.TryGetProperty("clientInfo", out var clientInfo));
197-
Assert.Equal("example-editor", clientInfo.GetProperty("editorName").GetString());
197+
Assert.Equal("example-app", clientInfo.GetProperty("editorName").GetString());
198198
Assert.False(clientInfo.TryGetProperty("editorVersion", out _));
199199
Assert.False(clientInfo.TryGetProperty("extensionName", out _));
200200
Assert.False(clientInfo.TryGetProperty("extensionVersion", out _));
@@ -209,10 +209,10 @@ public async Task Connect_Omits_All_Empty_ClientInfo()
209209
Connection = RuntimeConnection.ForUri(server.Url),
210210
ClientInfo = new CopilotClientInfo
211211
{
212-
EditorName = "",
213-
EditorVersion = "",
214-
ExtensionName = "",
215-
ExtensionVersion = "",
212+
ApplicationName = "",
213+
ApplicationVersion = "",
214+
IntegrationName = "",
215+
IntegrationVersion = "",
216216
},
217217
});
218218
await client.StartAsync();

go/client_test.go

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -300,10 +300,10 @@ func TestClient_ClientInfo(t *testing.T) {
300300
client := NewClient(&ClientOptions{
301301
Connection: URIConnection{URL: url},
302302
ClientInfo: &ClientInfo{
303-
EditorName: "JetBrains-IU",
304-
EditorVersion: "2026.1",
305-
ExtensionName: "copilot-intellij",
306-
ExtensionVersion: "1.5.0",
303+
ApplicationName: "acme-developer-portal",
304+
ApplicationVersion: "2.4.0",
305+
IntegrationName: "copilot-assistant",
306+
IntegrationVersion: "1.5.0",
307307
},
308308
})
309309
if err := client.Start(t.Context()); err != nil {
@@ -313,9 +313,9 @@ func TestClient_ClientInfo(t *testing.T) {
313313

314314
params := findConnect(requests())
315315
want := map[string]any{
316-
"editorName": "JetBrains-IU",
317-
"editorVersion": "2026.1",
318-
"extensionName": "copilot-intellij",
316+
"editorName": "acme-developer-portal",
317+
"editorVersion": "2.4.0",
318+
"extensionName": "copilot-assistant",
319319
"extensionVersion": "1.5.0",
320320
}
321321
if !reflect.DeepEqual(params["clientInfo"], want) {
@@ -344,14 +344,14 @@ func TestClient_ClientInfo(t *testing.T) {
344344

345345
client := NewClient(&ClientOptions{
346346
Connection: URIConnection{URL: url},
347-
ClientInfo: &ClientInfo{EditorName: "example-editor"},
347+
ClientInfo: &ClientInfo{ApplicationName: "example-app"},
348348
})
349349
if err := client.Start(t.Context()); err != nil {
350350
t.Fatalf("Start failed: %v", err)
351351
}
352352
defer client.ForceStop()
353353

354-
want := map[string]any{"editorName": "example-editor"}
354+
want := map[string]any{"editorName": "example-app"}
355355
if got := findConnect(requests())["clientInfo"]; !reflect.DeepEqual(got, want) {
356356
t.Fatalf("clientInfo = %v, want %v", got, want)
357357
}

0 commit comments

Comments
 (0)