@github/copilot-sdk 1.0.13-preview.1 → 1.0.13-preview.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -0
- package/dist/cjs/client.js +95 -4
- package/dist/cjs/generated/rpc.js +19 -0
- package/dist/cjs/session.js +16 -1
- package/dist/client.d.ts +5 -0
- package/dist/client.js +95 -4
- package/dist/generated/rpc.d.ts +46 -9
- package/dist/generated/rpc.js +19 -0
- package/dist/generated/session-events.d.ts +1056 -237
- package/dist/index.d.ts +1 -1
- package/dist/session.d.ts +1 -0
- package/dist/session.js +16 -1
- package/dist/types.d.ts +30 -3
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -137,12 +137,25 @@ Create a new conversation session.
|
|
|
137
137
|
- `infiniteSessions?: InfiniteSessionConfig` - Configure automatic context compaction (see below)
|
|
138
138
|
- `workingDirectory?: string` - Working directory for the session (default: runtime process cwd).
|
|
139
139
|
- `enableSessionStore?: boolean` - Enables the cross-session store for search and retrieval across sessions. When unset in `"copilot-cli"` mode, the runtime default applies (enabled). In `"empty"` mode, defaults to disabled.
|
|
140
|
+
- `gitHubTokenProvider?: GitHubTokenProvider` - Acquires rotating, session-scoped GitHub tokens. Token results require a positive `expiresIn` value in seconds remaining when the callback completes; production tokens typically last eight hours. Cannot be combined with `gitHubToken`.
|
|
140
141
|
- `provider?: ProviderConfig` - Custom API provider configuration (BYOK - Bring Your Own Key). See [Custom Providers](#custom-providers) section.
|
|
141
142
|
- `onPermissionRequest?: PermissionHandler` - Optional handler called before each tool execution to approve or deny it. When omitted, permission requests are emitted as events and left pending for manual resolution. `approveAll` approves requests when managed settings are disabled and throws when `enableManagedSettings` is true. Custom handlers can inspect `managedApprovalRequired` for human-facing confirmation logic. See [Permission Handling](#permission-handling) section.
|
|
142
143
|
- `onUserInputRequest?: UserInputHandler` - Handler for user input requests from the agent. Enables the `ask_user` tool. See [User Input Requests](#user-input-requests) section.
|
|
143
144
|
- `onElicitationRequest?: ElicitationHandler` - Handler for elicitation requests dispatched by the server. Enables this client to present form-based UI dialogs on behalf of the agent or other session participants. See [Elicitation Requests](#elicitation-requests) section.
|
|
144
145
|
- `hooks?: SessionHooks` - Hook handlers for session lifecycle events. See [Session Hooks](#session-hooks) section.
|
|
145
146
|
|
|
147
|
+
```typescript
|
|
148
|
+
const session = await client.createSession({
|
|
149
|
+
gitHubTokenProvider: async ({ host }) => ({
|
|
150
|
+
kind: "token",
|
|
151
|
+
accessToken: await acquireTokenForHost(host),
|
|
152
|
+
expiresIn: 8 * 60 * 60,
|
|
153
|
+
}),
|
|
154
|
+
});
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
Initial acquisition runs during session creation or resume. Cancellation, provider errors, and invalid token responses reject that operation instead of falling back to ambient authentication. Idle sessions refresh only before their next credential-consuming operation; there is no background refresh timer.
|
|
158
|
+
|
|
146
159
|
##### `resumeSession(sessionId: string, config?: ResumeSessionConfig): Promise<CopilotSession>`
|
|
147
160
|
|
|
148
161
|
Resume an existing session. Returns the session with `workspacePath` populated if infinite sessions were enabled.
|
package/dist/cjs/client.js
CHANGED
|
@@ -294,6 +294,7 @@ class CopilotClient {
|
|
|
294
294
|
builtinPluginDirectories = [];
|
|
295
295
|
onGitHubTelemetry;
|
|
296
296
|
clientGlobalHandlers = {};
|
|
297
|
+
githubTokenProviders = /* @__PURE__ */ new Map();
|
|
297
298
|
/**
|
|
298
299
|
* Typed server-scoped RPC methods.
|
|
299
300
|
* @throws Error if the client is not connected
|
|
@@ -551,8 +552,53 @@ class CopilotClient {
|
|
|
551
552
|
}
|
|
552
553
|
};
|
|
553
554
|
}
|
|
555
|
+
handlers.gitHubToken = {
|
|
556
|
+
getToken: (params) => this.acquireGitHubToken(params)
|
|
557
|
+
};
|
|
554
558
|
this.clientGlobalHandlers = handlers;
|
|
555
559
|
}
|
|
560
|
+
async acquireGitHubToken(params) {
|
|
561
|
+
const registration = this.githubTokenProviders.get(params.registrationId);
|
|
562
|
+
if (!registration) {
|
|
563
|
+
throw new Error(
|
|
564
|
+
`No GitHub token provider registered for registration ID "${params.registrationId}"`
|
|
565
|
+
);
|
|
566
|
+
}
|
|
567
|
+
return await registration.provider({
|
|
568
|
+
host: params.host,
|
|
569
|
+
sessionId: params.sessionId ?? registration.sessionId,
|
|
570
|
+
reason: params.reason
|
|
571
|
+
});
|
|
572
|
+
}
|
|
573
|
+
registerGitHubTokenProvider(provider, sessionId) {
|
|
574
|
+
if (!provider) {
|
|
575
|
+
return void 0;
|
|
576
|
+
}
|
|
577
|
+
const registrationId = (0, import_node_crypto.randomUUID)();
|
|
578
|
+
this.githubTokenProviders.set(registrationId, { provider, sessionId, committed: false });
|
|
579
|
+
return registrationId;
|
|
580
|
+
}
|
|
581
|
+
assignGitHubTokenProvider(registrationId, sessionId) {
|
|
582
|
+
if (!registrationId) {
|
|
583
|
+
return;
|
|
584
|
+
}
|
|
585
|
+
const registration = this.githubTokenProviders.get(registrationId);
|
|
586
|
+
if (registration) {
|
|
587
|
+
registration.sessionId = sessionId;
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
commitGitHubTokenProvider(sessionId, registrationId) {
|
|
591
|
+
for (const [candidateId, registration2] of this.githubTokenProviders) {
|
|
592
|
+
if (registration2.sessionId === sessionId && registration2.committed) {
|
|
593
|
+
this.githubTokenProviders.delete(candidateId);
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
const registration = registrationId ? this.githubTokenProviders.get(registrationId) : void 0;
|
|
597
|
+
if (registration) {
|
|
598
|
+
registration.sessionId = sessionId;
|
|
599
|
+
registration.committed = true;
|
|
600
|
+
}
|
|
601
|
+
}
|
|
556
602
|
/**
|
|
557
603
|
* Starts the CLI server and establishes a connection.
|
|
558
604
|
*
|
|
@@ -669,6 +715,7 @@ class CopilotClient {
|
|
|
669
715
|
session._markDisconnected();
|
|
670
716
|
}
|
|
671
717
|
this.sessions.clear();
|
|
718
|
+
this.githubTokenProviders.clear();
|
|
672
719
|
if (this.connection && (this.cliProcess || this.ffiHost) && !this.isExternalServer) {
|
|
673
720
|
const runtimeShutdownStart = Date.now();
|
|
674
721
|
const shutdownPromise = this.rpc.runtime.shutdown();
|
|
@@ -823,6 +870,7 @@ class CopilotClient {
|
|
|
823
870
|
session._markDisconnected();
|
|
824
871
|
}
|
|
825
872
|
this.sessions.clear();
|
|
873
|
+
this.githubTokenProviders.clear();
|
|
826
874
|
if (this.messageWriter) {
|
|
827
875
|
this.messageWriter.suppressWriteErrors = true;
|
|
828
876
|
}
|
|
@@ -1026,6 +1074,9 @@ class CopilotClient {
|
|
|
1026
1074
|
}
|
|
1027
1075
|
}
|
|
1028
1076
|
async createSession(config) {
|
|
1077
|
+
if (config.gitHubToken !== void 0 && config.gitHubTokenProvider !== void 0) {
|
|
1078
|
+
throw new Error("gitHubToken and gitHubTokenProvider are mutually exclusive");
|
|
1079
|
+
}
|
|
1029
1080
|
if (!this.connection) {
|
|
1030
1081
|
await this.start();
|
|
1031
1082
|
}
|
|
@@ -1036,6 +1087,11 @@ class CopilotClient {
|
|
|
1036
1087
|
const callerSessionId = config.sessionId;
|
|
1037
1088
|
const useServerGeneratedId = config.cloud != null && callerSessionId == null;
|
|
1038
1089
|
const localSessionId = useServerGeneratedId ? void 0 : callerSessionId ?? (0, import_node_crypto.randomUUID)();
|
|
1090
|
+
const toolFilterOptions = this.resolveToolFilterOptions(config);
|
|
1091
|
+
const gitHubTokenProviderRegistrationId = this.registerGitHubTokenProvider(
|
|
1092
|
+
config.gitHubTokenProvider,
|
|
1093
|
+
localSessionId
|
|
1094
|
+
);
|
|
1039
1095
|
const {
|
|
1040
1096
|
wireProvider: bearerWireProvider,
|
|
1041
1097
|
wireProviders: bearerWireProviders,
|
|
@@ -1052,7 +1108,10 @@ class CopilotClient {
|
|
|
1052
1108
|
this.onGetTraceContext,
|
|
1053
1109
|
{
|
|
1054
1110
|
mcpAuthHandler: config.onMcpAuthRequest,
|
|
1055
|
-
managedSettingsEnabled: config.enableManagedSettings === true || config.managedSettings !== void 0
|
|
1111
|
+
managedSettingsEnabled: config.enableManagedSettings === true || config.managedSettings !== void 0,
|
|
1112
|
+
onDisconnected: gitHubTokenProviderRegistrationId === void 0 ? void 0 : () => this.githubTokenProviders.delete(
|
|
1113
|
+
gitHubTokenProviderRegistrationId
|
|
1114
|
+
)
|
|
1056
1115
|
}
|
|
1057
1116
|
);
|
|
1058
1117
|
s.registerTools(config.tools);
|
|
@@ -1090,10 +1149,16 @@ class CopilotClient {
|
|
|
1090
1149
|
let session;
|
|
1091
1150
|
let registeredId;
|
|
1092
1151
|
if (localSessionId !== void 0) {
|
|
1093
|
-
|
|
1094
|
-
|
|
1152
|
+
try {
|
|
1153
|
+
session = initializeSession(localSessionId);
|
|
1154
|
+
registeredId = localSessionId;
|
|
1155
|
+
} catch (error) {
|
|
1156
|
+
if (gitHubTokenProviderRegistrationId !== void 0) {
|
|
1157
|
+
this.githubTokenProviders.delete(gitHubTokenProviderRegistrationId);
|
|
1158
|
+
}
|
|
1159
|
+
throw error;
|
|
1160
|
+
}
|
|
1095
1161
|
}
|
|
1096
|
-
const toolFilterOptions = this.resolveToolFilterOptions(config);
|
|
1097
1162
|
try {
|
|
1098
1163
|
const response = await this.connection.sendRequest("session.create", {
|
|
1099
1164
|
...await (0, import_telemetry.getTraceContext)(this.onGetTraceContext),
|
|
@@ -1178,6 +1243,7 @@ class CopilotClient {
|
|
|
1178
1243
|
infiniteSessions: config.infiniteSessions,
|
|
1179
1244
|
memory: config.memory,
|
|
1180
1245
|
gitHubToken: config.gitHubToken,
|
|
1246
|
+
gitHubTokenProviderRegistrationId,
|
|
1181
1247
|
remoteSession: config.remoteSession,
|
|
1182
1248
|
cloud: config.cloud,
|
|
1183
1249
|
expAssignments: config.expAssignments,
|
|
@@ -1201,6 +1267,7 @@ class CopilotClient {
|
|
|
1201
1267
|
session = initializeSession(returnedSessionId);
|
|
1202
1268
|
registeredId = returnedSessionId;
|
|
1203
1269
|
}
|
|
1270
|
+
this.assignGitHubTokenProvider(gitHubTokenProviderRegistrationId, returnedSessionId);
|
|
1204
1271
|
if (config.onMcpAuthRequest) {
|
|
1205
1272
|
await this.connection.sendRequest("session.eventLog.registerInterest", {
|
|
1206
1273
|
sessionId: returnedSessionId,
|
|
@@ -1210,10 +1277,14 @@ class CopilotClient {
|
|
|
1210
1277
|
session["_workspacePath"] = workspacePath;
|
|
1211
1278
|
session.setCapabilities(capabilities);
|
|
1212
1279
|
await this.updateSessionOptionsForMode(session, config);
|
|
1280
|
+
this.commitGitHubTokenProvider(returnedSessionId, gitHubTokenProviderRegistrationId);
|
|
1213
1281
|
} catch (e) {
|
|
1214
1282
|
if (registeredId !== void 0) {
|
|
1215
1283
|
this.sessions.delete(registeredId);
|
|
1216
1284
|
}
|
|
1285
|
+
if (gitHubTokenProviderRegistrationId !== void 0) {
|
|
1286
|
+
this.githubTokenProviders.delete(gitHubTokenProviderRegistrationId);
|
|
1287
|
+
}
|
|
1217
1288
|
throw e;
|
|
1218
1289
|
}
|
|
1219
1290
|
return session;
|
|
@@ -1250,6 +1321,9 @@ class CopilotClient {
|
|
|
1250
1321
|
return this.resumeSessionInternal(sessionId, config, factories, extensionOptions);
|
|
1251
1322
|
}
|
|
1252
1323
|
async resumeSessionInternal(sessionId, config, factories, extensionOptions) {
|
|
1324
|
+
if (config.gitHubToken !== void 0 && config.gitHubTokenProvider !== void 0) {
|
|
1325
|
+
throw new Error("gitHubToken and gitHubTokenProvider are mutually exclusive");
|
|
1326
|
+
}
|
|
1253
1327
|
if (!this.connection) {
|
|
1254
1328
|
await this.start();
|
|
1255
1329
|
}
|
|
@@ -1307,6 +1381,15 @@ class CopilotClient {
|
|
|
1307
1381
|
this.sessions.set(sessionId, session);
|
|
1308
1382
|
this.setupSessionFs(session, config);
|
|
1309
1383
|
const toolFilterOptions = this.resolveToolFilterOptions(config);
|
|
1384
|
+
const gitHubTokenProviderRegistrationId = this.registerGitHubTokenProvider(
|
|
1385
|
+
config.gitHubTokenProvider,
|
|
1386
|
+
sessionId
|
|
1387
|
+
);
|
|
1388
|
+
if (gitHubTokenProviderRegistrationId !== void 0) {
|
|
1389
|
+
session._setOnDisconnected(
|
|
1390
|
+
() => this.githubTokenProviders.delete(gitHubTokenProviderRegistrationId)
|
|
1391
|
+
);
|
|
1392
|
+
}
|
|
1310
1393
|
try {
|
|
1311
1394
|
const response = await this.connection.sendRequest("session.resume", {
|
|
1312
1395
|
...await (0, import_telemetry.getTraceContext)(this.onGetTraceContext),
|
|
@@ -1394,6 +1477,7 @@ class CopilotClient {
|
|
|
1394
1477
|
disableResume: config.suppressResumeEvent,
|
|
1395
1478
|
continuePendingWork: config.continuePendingWork,
|
|
1396
1479
|
gitHubToken: config.gitHubToken,
|
|
1480
|
+
gitHubTokenProviderRegistrationId,
|
|
1397
1481
|
remoteSession: config.remoteSession,
|
|
1398
1482
|
openCanvases: config.openCanvases,
|
|
1399
1483
|
expAssignments: config.expAssignments,
|
|
@@ -1423,8 +1507,12 @@ class CopilotClient {
|
|
|
1423
1507
|
});
|
|
1424
1508
|
}
|
|
1425
1509
|
await this.updateSessionOptionsForMode(session, config);
|
|
1510
|
+
this.commitGitHubTokenProvider(sessionId, gitHubTokenProviderRegistrationId);
|
|
1426
1511
|
} catch (e) {
|
|
1427
1512
|
this.sessions.delete(sessionId);
|
|
1513
|
+
if (gitHubTokenProviderRegistrationId !== void 0) {
|
|
1514
|
+
this.githubTokenProviders.delete(gitHubTokenProviderRegistrationId);
|
|
1515
|
+
}
|
|
1428
1516
|
throw e;
|
|
1429
1517
|
}
|
|
1430
1518
|
return session;
|
|
@@ -1613,7 +1701,9 @@ class CopilotClient {
|
|
|
1613
1701
|
if (!success) {
|
|
1614
1702
|
throw new Error(`Failed to delete session ${sessionId}: ${error || "Unknown error"}`);
|
|
1615
1703
|
}
|
|
1704
|
+
const session = this.sessions.get(sessionId);
|
|
1616
1705
|
this.sessions.delete(sessionId);
|
|
1706
|
+
session?._runOnDisconnected();
|
|
1617
1707
|
}
|
|
1618
1708
|
/**
|
|
1619
1709
|
* List all available sessions.
|
|
@@ -2161,6 +2251,7 @@ stderr: ${stderrOutput}`
|
|
|
2161
2251
|
);
|
|
2162
2252
|
this.connection.onClose(() => {
|
|
2163
2253
|
this.state = "disconnected";
|
|
2254
|
+
this.githubTokenProviders.clear();
|
|
2164
2255
|
});
|
|
2165
2256
|
this.connection.onError((_error) => {
|
|
2166
2257
|
this.state = "disconnected";
|
|
@@ -2540,6 +2540,25 @@ function createInternalSessionRpc(connection, sessionId) {
|
|
|
2540
2540
|
}
|
|
2541
2541
|
},
|
|
2542
2542
|
/** @experimental */
|
|
2543
|
+
factory: {
|
|
2544
|
+
/**
|
|
2545
|
+
* Internal tool-originated factory invocation.
|
|
2546
|
+
*
|
|
2547
|
+
* @param params Internal parameters for invoking a registered factory from a tool.
|
|
2548
|
+
*
|
|
2549
|
+
* @returns Complete current or terminal factory run envelope.
|
|
2550
|
+
*/
|
|
2551
|
+
runFromTool: async (params) => connection.sendRequest("session.factory.runFromTool", { sessionId, ...params }),
|
|
2552
|
+
/**
|
|
2553
|
+
* Internal tool-originated factory resume.
|
|
2554
|
+
*
|
|
2555
|
+
* @param params Internal parameters for resuming a factory run from a tool.
|
|
2556
|
+
*
|
|
2557
|
+
* @returns Resolved persisted factory identity and resumed run envelope.
|
|
2558
|
+
*/
|
|
2559
|
+
resumeFromTool: async (params) => connection.sendRequest("session.factory.resumeFromTool", { sessionId, ...params })
|
|
2560
|
+
},
|
|
2561
|
+
/** @experimental */
|
|
2543
2562
|
model: {
|
|
2544
2563
|
/**
|
|
2545
2564
|
* Resolves and applies organization-managed and repository model overlays.
|
package/dist/cjs/session.js
CHANGED
|
@@ -241,6 +241,7 @@ class CopilotSession {
|
|
|
241
241
|
this.traceContextProvider = traceContextProvider;
|
|
242
242
|
this.mcpAuthHandler = options?.mcpAuthHandler;
|
|
243
243
|
this.managedSettingsEnabled = options?.managedSettingsEnabled === true;
|
|
244
|
+
this.onDisconnected = options?.onDisconnected;
|
|
244
245
|
}
|
|
245
246
|
sessionId;
|
|
246
247
|
connection;
|
|
@@ -267,6 +268,7 @@ class CopilotSession {
|
|
|
267
268
|
_capabilities = {};
|
|
268
269
|
openCanvasInstances = [];
|
|
269
270
|
disconnected = false;
|
|
271
|
+
onDisconnected;
|
|
270
272
|
/** @internal Client session API handlers, populated by CopilotClient during create/resume. */
|
|
271
273
|
clientSessionApis = {};
|
|
272
274
|
/**
|
|
@@ -475,7 +477,7 @@ class CopilotSession {
|
|
|
475
477
|
const unsubscribe = this.on((event) => {
|
|
476
478
|
if (event.type === "assistant.message") {
|
|
477
479
|
lastAssistantMessage = event;
|
|
478
|
-
} else if (event.type === "session.idle") {
|
|
480
|
+
} else if (event.type === "session.idle" && event.data.mode !== "autopilot") {
|
|
479
481
|
resolveOutcome({ kind: "idle" });
|
|
480
482
|
} else if (event.type === "session.error") {
|
|
481
483
|
const error = new Error(event.data.message);
|
|
@@ -510,7 +512,11 @@ class CopilotSession {
|
|
|
510
512
|
}
|
|
511
513
|
/** @internal */
|
|
512
514
|
_markDisconnected() {
|
|
515
|
+
if (this.disconnected) {
|
|
516
|
+
return;
|
|
517
|
+
}
|
|
513
518
|
this.disconnected = true;
|
|
519
|
+
this._runOnDisconnected();
|
|
514
520
|
this.eventHandlers.clear();
|
|
515
521
|
this.typedEventHandlers.clear();
|
|
516
522
|
this.toolHandlers.clear();
|
|
@@ -530,6 +536,15 @@ class CopilotSession {
|
|
|
530
536
|
this.factoryAbortControllers.clear();
|
|
531
537
|
this.transformCallbacks?.clear();
|
|
532
538
|
}
|
|
539
|
+
/** @internal */
|
|
540
|
+
_runOnDisconnected() {
|
|
541
|
+
this.onDisconnected?.();
|
|
542
|
+
this.onDisconnected = void 0;
|
|
543
|
+
}
|
|
544
|
+
/** @internal */
|
|
545
|
+
_setOnDisconnected(callback) {
|
|
546
|
+
this.onDisconnected = callback;
|
|
547
|
+
}
|
|
533
548
|
on(eventTypeOrHandler, handler) {
|
|
534
549
|
if (typeof eventTypeOrHandler === "string" && handler) {
|
|
535
550
|
const eventType = eventTypeOrHandler;
|
package/dist/client.d.ts
CHANGED
|
@@ -40,6 +40,7 @@ export declare class CopilotClient {
|
|
|
40
40
|
private builtinPluginDirectories;
|
|
41
41
|
private onGitHubTelemetry?;
|
|
42
42
|
private clientGlobalHandlers;
|
|
43
|
+
private githubTokenProviders;
|
|
43
44
|
/**
|
|
44
45
|
* Typed server-scoped RPC methods.
|
|
45
46
|
* @throws Error if the client is not connected
|
|
@@ -96,6 +97,10 @@ export declare class CopilotClient {
|
|
|
96
97
|
private validateSessionFsConfig;
|
|
97
98
|
private setupSessionFs;
|
|
98
99
|
private setupClientGlobalHandlers;
|
|
100
|
+
private acquireGitHubToken;
|
|
101
|
+
private registerGitHubTokenProvider;
|
|
102
|
+
private assignGitHubTokenProvider;
|
|
103
|
+
private commitGitHubTokenProvider;
|
|
99
104
|
/**
|
|
100
105
|
* Starts the CLI server and establishes a connection.
|
|
101
106
|
*
|
package/dist/client.js
CHANGED
|
@@ -271,6 +271,7 @@ class CopilotClient {
|
|
|
271
271
|
builtinPluginDirectories = [];
|
|
272
272
|
onGitHubTelemetry;
|
|
273
273
|
clientGlobalHandlers = {};
|
|
274
|
+
githubTokenProviders = /* @__PURE__ */ new Map();
|
|
274
275
|
/**
|
|
275
276
|
* Typed server-scoped RPC methods.
|
|
276
277
|
* @throws Error if the client is not connected
|
|
@@ -528,8 +529,53 @@ class CopilotClient {
|
|
|
528
529
|
}
|
|
529
530
|
};
|
|
530
531
|
}
|
|
532
|
+
handlers.gitHubToken = {
|
|
533
|
+
getToken: (params) => this.acquireGitHubToken(params)
|
|
534
|
+
};
|
|
531
535
|
this.clientGlobalHandlers = handlers;
|
|
532
536
|
}
|
|
537
|
+
async acquireGitHubToken(params) {
|
|
538
|
+
const registration = this.githubTokenProviders.get(params.registrationId);
|
|
539
|
+
if (!registration) {
|
|
540
|
+
throw new Error(
|
|
541
|
+
`No GitHub token provider registered for registration ID "${params.registrationId}"`
|
|
542
|
+
);
|
|
543
|
+
}
|
|
544
|
+
return await registration.provider({
|
|
545
|
+
host: params.host,
|
|
546
|
+
sessionId: params.sessionId ?? registration.sessionId,
|
|
547
|
+
reason: params.reason
|
|
548
|
+
});
|
|
549
|
+
}
|
|
550
|
+
registerGitHubTokenProvider(provider, sessionId) {
|
|
551
|
+
if (!provider) {
|
|
552
|
+
return void 0;
|
|
553
|
+
}
|
|
554
|
+
const registrationId = randomUUID();
|
|
555
|
+
this.githubTokenProviders.set(registrationId, { provider, sessionId, committed: false });
|
|
556
|
+
return registrationId;
|
|
557
|
+
}
|
|
558
|
+
assignGitHubTokenProvider(registrationId, sessionId) {
|
|
559
|
+
if (!registrationId) {
|
|
560
|
+
return;
|
|
561
|
+
}
|
|
562
|
+
const registration = this.githubTokenProviders.get(registrationId);
|
|
563
|
+
if (registration) {
|
|
564
|
+
registration.sessionId = sessionId;
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
commitGitHubTokenProvider(sessionId, registrationId) {
|
|
568
|
+
for (const [candidateId, registration2] of this.githubTokenProviders) {
|
|
569
|
+
if (registration2.sessionId === sessionId && registration2.committed) {
|
|
570
|
+
this.githubTokenProviders.delete(candidateId);
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
const registration = registrationId ? this.githubTokenProviders.get(registrationId) : void 0;
|
|
574
|
+
if (registration) {
|
|
575
|
+
registration.sessionId = sessionId;
|
|
576
|
+
registration.committed = true;
|
|
577
|
+
}
|
|
578
|
+
}
|
|
533
579
|
/**
|
|
534
580
|
* Starts the CLI server and establishes a connection.
|
|
535
581
|
*
|
|
@@ -646,6 +692,7 @@ class CopilotClient {
|
|
|
646
692
|
session._markDisconnected();
|
|
647
693
|
}
|
|
648
694
|
this.sessions.clear();
|
|
695
|
+
this.githubTokenProviders.clear();
|
|
649
696
|
if (this.connection && (this.cliProcess || this.ffiHost) && !this.isExternalServer) {
|
|
650
697
|
const runtimeShutdownStart = Date.now();
|
|
651
698
|
const shutdownPromise = this.rpc.runtime.shutdown();
|
|
@@ -800,6 +847,7 @@ class CopilotClient {
|
|
|
800
847
|
session._markDisconnected();
|
|
801
848
|
}
|
|
802
849
|
this.sessions.clear();
|
|
850
|
+
this.githubTokenProviders.clear();
|
|
803
851
|
if (this.messageWriter) {
|
|
804
852
|
this.messageWriter.suppressWriteErrors = true;
|
|
805
853
|
}
|
|
@@ -1003,6 +1051,9 @@ class CopilotClient {
|
|
|
1003
1051
|
}
|
|
1004
1052
|
}
|
|
1005
1053
|
async createSession(config) {
|
|
1054
|
+
if (config.gitHubToken !== void 0 && config.gitHubTokenProvider !== void 0) {
|
|
1055
|
+
throw new Error("gitHubToken and gitHubTokenProvider are mutually exclusive");
|
|
1056
|
+
}
|
|
1006
1057
|
if (!this.connection) {
|
|
1007
1058
|
await this.start();
|
|
1008
1059
|
}
|
|
@@ -1013,6 +1064,11 @@ class CopilotClient {
|
|
|
1013
1064
|
const callerSessionId = config.sessionId;
|
|
1014
1065
|
const useServerGeneratedId = config.cloud != null && callerSessionId == null;
|
|
1015
1066
|
const localSessionId = useServerGeneratedId ? void 0 : callerSessionId ?? randomUUID();
|
|
1067
|
+
const toolFilterOptions = this.resolveToolFilterOptions(config);
|
|
1068
|
+
const gitHubTokenProviderRegistrationId = this.registerGitHubTokenProvider(
|
|
1069
|
+
config.gitHubTokenProvider,
|
|
1070
|
+
localSessionId
|
|
1071
|
+
);
|
|
1016
1072
|
const {
|
|
1017
1073
|
wireProvider: bearerWireProvider,
|
|
1018
1074
|
wireProviders: bearerWireProviders,
|
|
@@ -1029,7 +1085,10 @@ class CopilotClient {
|
|
|
1029
1085
|
this.onGetTraceContext,
|
|
1030
1086
|
{
|
|
1031
1087
|
mcpAuthHandler: config.onMcpAuthRequest,
|
|
1032
|
-
managedSettingsEnabled: config.enableManagedSettings === true || config.managedSettings !== void 0
|
|
1088
|
+
managedSettingsEnabled: config.enableManagedSettings === true || config.managedSettings !== void 0,
|
|
1089
|
+
onDisconnected: gitHubTokenProviderRegistrationId === void 0 ? void 0 : () => this.githubTokenProviders.delete(
|
|
1090
|
+
gitHubTokenProviderRegistrationId
|
|
1091
|
+
)
|
|
1033
1092
|
}
|
|
1034
1093
|
);
|
|
1035
1094
|
s.registerTools(config.tools);
|
|
@@ -1067,10 +1126,16 @@ class CopilotClient {
|
|
|
1067
1126
|
let session;
|
|
1068
1127
|
let registeredId;
|
|
1069
1128
|
if (localSessionId !== void 0) {
|
|
1070
|
-
|
|
1071
|
-
|
|
1129
|
+
try {
|
|
1130
|
+
session = initializeSession(localSessionId);
|
|
1131
|
+
registeredId = localSessionId;
|
|
1132
|
+
} catch (error) {
|
|
1133
|
+
if (gitHubTokenProviderRegistrationId !== void 0) {
|
|
1134
|
+
this.githubTokenProviders.delete(gitHubTokenProviderRegistrationId);
|
|
1135
|
+
}
|
|
1136
|
+
throw error;
|
|
1137
|
+
}
|
|
1072
1138
|
}
|
|
1073
|
-
const toolFilterOptions = this.resolveToolFilterOptions(config);
|
|
1074
1139
|
try {
|
|
1075
1140
|
const response = await this.connection.sendRequest("session.create", {
|
|
1076
1141
|
...await getTraceContext(this.onGetTraceContext),
|
|
@@ -1155,6 +1220,7 @@ class CopilotClient {
|
|
|
1155
1220
|
infiniteSessions: config.infiniteSessions,
|
|
1156
1221
|
memory: config.memory,
|
|
1157
1222
|
gitHubToken: config.gitHubToken,
|
|
1223
|
+
gitHubTokenProviderRegistrationId,
|
|
1158
1224
|
remoteSession: config.remoteSession,
|
|
1159
1225
|
cloud: config.cloud,
|
|
1160
1226
|
expAssignments: config.expAssignments,
|
|
@@ -1178,6 +1244,7 @@ class CopilotClient {
|
|
|
1178
1244
|
session = initializeSession(returnedSessionId);
|
|
1179
1245
|
registeredId = returnedSessionId;
|
|
1180
1246
|
}
|
|
1247
|
+
this.assignGitHubTokenProvider(gitHubTokenProviderRegistrationId, returnedSessionId);
|
|
1181
1248
|
if (config.onMcpAuthRequest) {
|
|
1182
1249
|
await this.connection.sendRequest("session.eventLog.registerInterest", {
|
|
1183
1250
|
sessionId: returnedSessionId,
|
|
@@ -1187,10 +1254,14 @@ class CopilotClient {
|
|
|
1187
1254
|
session["_workspacePath"] = workspacePath;
|
|
1188
1255
|
session.setCapabilities(capabilities);
|
|
1189
1256
|
await this.updateSessionOptionsForMode(session, config);
|
|
1257
|
+
this.commitGitHubTokenProvider(returnedSessionId, gitHubTokenProviderRegistrationId);
|
|
1190
1258
|
} catch (e) {
|
|
1191
1259
|
if (registeredId !== void 0) {
|
|
1192
1260
|
this.sessions.delete(registeredId);
|
|
1193
1261
|
}
|
|
1262
|
+
if (gitHubTokenProviderRegistrationId !== void 0) {
|
|
1263
|
+
this.githubTokenProviders.delete(gitHubTokenProviderRegistrationId);
|
|
1264
|
+
}
|
|
1194
1265
|
throw e;
|
|
1195
1266
|
}
|
|
1196
1267
|
return session;
|
|
@@ -1227,6 +1298,9 @@ class CopilotClient {
|
|
|
1227
1298
|
return this.resumeSessionInternal(sessionId, config, factories, extensionOptions);
|
|
1228
1299
|
}
|
|
1229
1300
|
async resumeSessionInternal(sessionId, config, factories, extensionOptions) {
|
|
1301
|
+
if (config.gitHubToken !== void 0 && config.gitHubTokenProvider !== void 0) {
|
|
1302
|
+
throw new Error("gitHubToken and gitHubTokenProvider are mutually exclusive");
|
|
1303
|
+
}
|
|
1230
1304
|
if (!this.connection) {
|
|
1231
1305
|
await this.start();
|
|
1232
1306
|
}
|
|
@@ -1284,6 +1358,15 @@ class CopilotClient {
|
|
|
1284
1358
|
this.sessions.set(sessionId, session);
|
|
1285
1359
|
this.setupSessionFs(session, config);
|
|
1286
1360
|
const toolFilterOptions = this.resolveToolFilterOptions(config);
|
|
1361
|
+
const gitHubTokenProviderRegistrationId = this.registerGitHubTokenProvider(
|
|
1362
|
+
config.gitHubTokenProvider,
|
|
1363
|
+
sessionId
|
|
1364
|
+
);
|
|
1365
|
+
if (gitHubTokenProviderRegistrationId !== void 0) {
|
|
1366
|
+
session._setOnDisconnected(
|
|
1367
|
+
() => this.githubTokenProviders.delete(gitHubTokenProviderRegistrationId)
|
|
1368
|
+
);
|
|
1369
|
+
}
|
|
1287
1370
|
try {
|
|
1288
1371
|
const response = await this.connection.sendRequest("session.resume", {
|
|
1289
1372
|
...await getTraceContext(this.onGetTraceContext),
|
|
@@ -1371,6 +1454,7 @@ class CopilotClient {
|
|
|
1371
1454
|
disableResume: config.suppressResumeEvent,
|
|
1372
1455
|
continuePendingWork: config.continuePendingWork,
|
|
1373
1456
|
gitHubToken: config.gitHubToken,
|
|
1457
|
+
gitHubTokenProviderRegistrationId,
|
|
1374
1458
|
remoteSession: config.remoteSession,
|
|
1375
1459
|
openCanvases: config.openCanvases,
|
|
1376
1460
|
expAssignments: config.expAssignments,
|
|
@@ -1400,8 +1484,12 @@ class CopilotClient {
|
|
|
1400
1484
|
});
|
|
1401
1485
|
}
|
|
1402
1486
|
await this.updateSessionOptionsForMode(session, config);
|
|
1487
|
+
this.commitGitHubTokenProvider(sessionId, gitHubTokenProviderRegistrationId);
|
|
1403
1488
|
} catch (e) {
|
|
1404
1489
|
this.sessions.delete(sessionId);
|
|
1490
|
+
if (gitHubTokenProviderRegistrationId !== void 0) {
|
|
1491
|
+
this.githubTokenProviders.delete(gitHubTokenProviderRegistrationId);
|
|
1492
|
+
}
|
|
1405
1493
|
throw e;
|
|
1406
1494
|
}
|
|
1407
1495
|
return session;
|
|
@@ -1590,7 +1678,9 @@ class CopilotClient {
|
|
|
1590
1678
|
if (!success) {
|
|
1591
1679
|
throw new Error(`Failed to delete session ${sessionId}: ${error || "Unknown error"}`);
|
|
1592
1680
|
}
|
|
1681
|
+
const session = this.sessions.get(sessionId);
|
|
1593
1682
|
this.sessions.delete(sessionId);
|
|
1683
|
+
session?._runOnDisconnected();
|
|
1594
1684
|
}
|
|
1595
1685
|
/**
|
|
1596
1686
|
* List all available sessions.
|
|
@@ -2138,6 +2228,7 @@ stderr: ${stderrOutput}`
|
|
|
2138
2228
|
);
|
|
2139
2229
|
this.connection.onClose(() => {
|
|
2140
2230
|
this.state = "disconnected";
|
|
2231
|
+
this.githubTokenProviders.clear();
|
|
2141
2232
|
});
|
|
2142
2233
|
this.connection.onError((_error) => {
|
|
2143
2234
|
this.state = "disconnected";
|