@github/copilot-sdk 0.1.31-unstable.0 → 0.1.32
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 +14 -3
- package/dist/client.d.ts +25 -5
- package/dist/client.js +121 -11
- package/dist/generated/rpc.d.ts +21 -3
- package/dist/session.d.ts +39 -13
- package/dist/session.js +73 -18
- package/dist/types.d.ts +2 -4
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -52,10 +52,17 @@ await session.send({ prompt: "What is 2+2?" });
|
|
|
52
52
|
await done;
|
|
53
53
|
|
|
54
54
|
// Clean up
|
|
55
|
-
await session.
|
|
55
|
+
await session.disconnect();
|
|
56
56
|
await client.stop();
|
|
57
57
|
```
|
|
58
58
|
|
|
59
|
+
Sessions also support `Symbol.asyncDispose` for use with [`await using`](https://github.com/tc39/proposal-explicit-resource-management) (TypeScript 5.2+/Node.js 18.0+):
|
|
60
|
+
|
|
61
|
+
```typescript
|
|
62
|
+
await using session = await client.createSession({ model: "gpt-5" });
|
|
63
|
+
// session is automatically disconnected when leaving scope
|
|
64
|
+
```
|
|
65
|
+
|
|
59
66
|
## API Reference
|
|
60
67
|
|
|
61
68
|
### CopilotClient
|
|
@@ -265,9 +272,13 @@ Abort the currently processing message in this session.
|
|
|
265
272
|
|
|
266
273
|
Get all events/messages from this session.
|
|
267
274
|
|
|
268
|
-
##### `
|
|
275
|
+
##### `disconnect(): Promise<void>`
|
|
276
|
+
|
|
277
|
+
Disconnect the session and free resources. Session data on disk is preserved for later resumption.
|
|
278
|
+
|
|
279
|
+
##### `destroy(): Promise<void>` *(deprecated)*
|
|
269
280
|
|
|
270
|
-
|
|
281
|
+
Deprecated — use `disconnect()` instead.
|
|
271
282
|
|
|
272
283
|
---
|
|
273
284
|
|
package/dist/client.d.ts
CHANGED
|
@@ -19,6 +19,7 @@ export declare class CopilotClient {
|
|
|
19
19
|
private typedLifecycleHandlers;
|
|
20
20
|
private _rpc;
|
|
21
21
|
private processExitPromise;
|
|
22
|
+
private negotiatedProtocolVersion;
|
|
22
23
|
/**
|
|
23
24
|
* Typed server-scoped RPC methods.
|
|
24
25
|
* @throws Error if the client is not connected
|
|
@@ -74,10 +75,14 @@ export declare class CopilotClient {
|
|
|
74
75
|
* Stops the CLI server and closes all active sessions.
|
|
75
76
|
*
|
|
76
77
|
* This method performs graceful cleanup:
|
|
77
|
-
* 1.
|
|
78
|
+
* 1. Closes all active sessions (releases in-memory resources)
|
|
78
79
|
* 2. Closes the JSON-RPC connection
|
|
79
80
|
* 3. Terminates the CLI server process (if spawned by this client)
|
|
80
81
|
*
|
|
82
|
+
* Note: session data on disk is preserved, so sessions can be resumed later.
|
|
83
|
+
* To permanently remove session data before stopping, call
|
|
84
|
+
* {@link deleteSession} for each session first.
|
|
85
|
+
*
|
|
81
86
|
* @returns A promise that resolves with an array of errors encountered during cleanup.
|
|
82
87
|
* An empty array indicates all cleanup succeeded.
|
|
83
88
|
*
|
|
@@ -220,7 +225,8 @@ export declare class CopilotClient {
|
|
|
220
225
|
*/
|
|
221
226
|
listModels(): Promise<ModelInfo[]>;
|
|
222
227
|
/**
|
|
223
|
-
* Verify that the server's protocol version
|
|
228
|
+
* Verify that the server's protocol version is within the supported range
|
|
229
|
+
* and store the negotiated version.
|
|
224
230
|
*/
|
|
225
231
|
private verifyProtocolVersion;
|
|
226
232
|
/**
|
|
@@ -242,10 +248,12 @@ export declare class CopilotClient {
|
|
|
242
248
|
*/
|
|
243
249
|
getLastSessionId(): Promise<string | undefined>;
|
|
244
250
|
/**
|
|
245
|
-
*
|
|
251
|
+
* Permanently deletes a session and all its data from disk, including
|
|
252
|
+
* conversation history, planning state, and artifacts.
|
|
246
253
|
*
|
|
247
|
-
*
|
|
248
|
-
*
|
|
254
|
+
* Unlike {@link CopilotSession.disconnect}, which only releases in-memory
|
|
255
|
+
* resources and preserves session data for later resumption, this method
|
|
256
|
+
* is irreversible. The session cannot be resumed after deletion.
|
|
249
257
|
*
|
|
250
258
|
* @param sessionId - The ID of the session to delete
|
|
251
259
|
* @returns A promise that resolves when the session is deleted
|
|
@@ -377,6 +385,18 @@ export declare class CopilotClient {
|
|
|
377
385
|
private handleSessionLifecycleNotification;
|
|
378
386
|
private handleUserInputRequest;
|
|
379
387
|
private handleHooksInvoke;
|
|
388
|
+
/**
|
|
389
|
+
* Handles a v2-style tool.call RPC request from the server.
|
|
390
|
+
* Looks up the session and tool handler, executes it, and returns the result
|
|
391
|
+
* in the v2 response format.
|
|
392
|
+
*/
|
|
393
|
+
private handleToolCallRequestV2;
|
|
394
|
+
/**
|
|
395
|
+
* Handles a v2-style permission.request RPC request from the server.
|
|
396
|
+
*/
|
|
397
|
+
private handlePermissionRequestV2;
|
|
398
|
+
private normalizeToolResultV2;
|
|
399
|
+
private isToolResultObject;
|
|
380
400
|
/**
|
|
381
401
|
* Attempt to reconnect to the server
|
|
382
402
|
*/
|
package/dist/client.js
CHANGED
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
import { createServerRpc } from "./generated/rpc.js";
|
|
12
12
|
import { getSdkProtocolVersion } from "./sdkProtocolVersion.js";
|
|
13
13
|
import { CopilotSession } from "./session.js";
|
|
14
|
+
const MIN_PROTOCOL_VERSION = 2;
|
|
14
15
|
function isZodSchema(value) {
|
|
15
16
|
return value != null && typeof value === "object" && "toJSONSchema" in value && typeof value.toJSONSchema === "function";
|
|
16
17
|
}
|
|
@@ -52,6 +53,7 @@ class CopilotClient {
|
|
|
52
53
|
_rpc = null;
|
|
53
54
|
processExitPromise = null;
|
|
54
55
|
// Rejects when CLI process exits
|
|
56
|
+
negotiatedProtocolVersion = null;
|
|
55
57
|
/**
|
|
56
58
|
* Typed server-scoped RPC methods.
|
|
57
59
|
* @throws Error if the client is not connected
|
|
@@ -188,10 +190,14 @@ class CopilotClient {
|
|
|
188
190
|
* Stops the CLI server and closes all active sessions.
|
|
189
191
|
*
|
|
190
192
|
* This method performs graceful cleanup:
|
|
191
|
-
* 1.
|
|
193
|
+
* 1. Closes all active sessions (releases in-memory resources)
|
|
192
194
|
* 2. Closes the JSON-RPC connection
|
|
193
195
|
* 3. Terminates the CLI server process (if spawned by this client)
|
|
194
196
|
*
|
|
197
|
+
* Note: session data on disk is preserved, so sessions can be resumed later.
|
|
198
|
+
* To permanently remove session data before stopping, call
|
|
199
|
+
* {@link deleteSession} for each session first.
|
|
200
|
+
*
|
|
195
201
|
* @returns A promise that resolves with an array of errors encountered during cleanup.
|
|
196
202
|
* An empty array indicates all cleanup succeeded.
|
|
197
203
|
*
|
|
@@ -210,7 +216,7 @@ class CopilotClient {
|
|
|
210
216
|
let lastError = null;
|
|
211
217
|
for (let attempt = 1; attempt <= 3; attempt++) {
|
|
212
218
|
try {
|
|
213
|
-
await session.
|
|
219
|
+
await session.disconnect();
|
|
214
220
|
lastError = null;
|
|
215
221
|
break;
|
|
216
222
|
} catch (error) {
|
|
@@ -224,7 +230,7 @@ class CopilotClient {
|
|
|
224
230
|
if (lastError) {
|
|
225
231
|
errors.push(
|
|
226
232
|
new Error(
|
|
227
|
-
`Failed to
|
|
233
|
+
`Failed to disconnect session ${sessionId} after 3 attempts: ${lastError.message}`
|
|
228
234
|
)
|
|
229
235
|
);
|
|
230
236
|
}
|
|
@@ -578,10 +584,11 @@ class CopilotClient {
|
|
|
578
584
|
}
|
|
579
585
|
}
|
|
580
586
|
/**
|
|
581
|
-
* Verify that the server's protocol version
|
|
587
|
+
* Verify that the server's protocol version is within the supported range
|
|
588
|
+
* and store the negotiated version.
|
|
582
589
|
*/
|
|
583
590
|
async verifyProtocolVersion() {
|
|
584
|
-
const
|
|
591
|
+
const maxVersion = getSdkProtocolVersion();
|
|
585
592
|
let pingResult;
|
|
586
593
|
if (this.processExitPromise) {
|
|
587
594
|
pingResult = await Promise.race([this.ping(), this.processExitPromise]);
|
|
@@ -591,14 +598,15 @@ class CopilotClient {
|
|
|
591
598
|
const serverVersion = pingResult.protocolVersion;
|
|
592
599
|
if (serverVersion === void 0) {
|
|
593
600
|
throw new Error(
|
|
594
|
-
`SDK protocol version mismatch: SDK
|
|
601
|
+
`SDK protocol version mismatch: SDK supports versions ${MIN_PROTOCOL_VERSION}-${maxVersion}, but server does not report a protocol version. Please update your server to ensure compatibility.`
|
|
595
602
|
);
|
|
596
603
|
}
|
|
597
|
-
if (serverVersion
|
|
604
|
+
if (serverVersion < MIN_PROTOCOL_VERSION || serverVersion > maxVersion) {
|
|
598
605
|
throw new Error(
|
|
599
|
-
`SDK protocol version mismatch: SDK
|
|
606
|
+
`SDK protocol version mismatch: SDK supports versions ${MIN_PROTOCOL_VERSION}-${maxVersion}, but server reports version ${serverVersion}. Please update your SDK or server to ensure compatibility.`
|
|
600
607
|
);
|
|
601
608
|
}
|
|
609
|
+
this.negotiatedProtocolVersion = serverVersion;
|
|
602
610
|
}
|
|
603
611
|
/**
|
|
604
612
|
* Gets the ID of the most recently updated session.
|
|
@@ -625,10 +633,12 @@ class CopilotClient {
|
|
|
625
633
|
return response.sessionId;
|
|
626
634
|
}
|
|
627
635
|
/**
|
|
628
|
-
*
|
|
636
|
+
* Permanently deletes a session and all its data from disk, including
|
|
637
|
+
* conversation history, planning state, and artifacts.
|
|
629
638
|
*
|
|
630
|
-
*
|
|
631
|
-
*
|
|
639
|
+
* Unlike {@link CopilotSession.disconnect}, which only releases in-memory
|
|
640
|
+
* resources and preserves session data for later resumption, this method
|
|
641
|
+
* is irreversible. The session cannot be resumed after deletion.
|
|
632
642
|
*
|
|
633
643
|
* @param sessionId - The ID of the session to delete
|
|
634
644
|
* @returns A promise that resolves when the session is deleted
|
|
@@ -969,6 +979,14 @@ stderr: ${stderrOutput}`
|
|
|
969
979
|
this.connection.onNotification("session.lifecycle", (notification) => {
|
|
970
980
|
this.handleSessionLifecycleNotification(notification);
|
|
971
981
|
});
|
|
982
|
+
this.connection.onRequest(
|
|
983
|
+
"tool.call",
|
|
984
|
+
async (params) => await this.handleToolCallRequestV2(params)
|
|
985
|
+
);
|
|
986
|
+
this.connection.onRequest(
|
|
987
|
+
"permission.request",
|
|
988
|
+
async (params) => await this.handlePermissionRequestV2(params)
|
|
989
|
+
);
|
|
972
990
|
this.connection.onRequest(
|
|
973
991
|
"userInput.request",
|
|
974
992
|
async (params) => await this.handleUserInputRequest(params)
|
|
@@ -1041,6 +1059,98 @@ stderr: ${stderrOutput}`
|
|
|
1041
1059
|
const output = await session._handleHooksInvoke(params.hookType, params.input);
|
|
1042
1060
|
return { output };
|
|
1043
1061
|
}
|
|
1062
|
+
// ========================================================================
|
|
1063
|
+
// Protocol v2 backward-compatibility adapters
|
|
1064
|
+
// ========================================================================
|
|
1065
|
+
/**
|
|
1066
|
+
* Handles a v2-style tool.call RPC request from the server.
|
|
1067
|
+
* Looks up the session and tool handler, executes it, and returns the result
|
|
1068
|
+
* in the v2 response format.
|
|
1069
|
+
*/
|
|
1070
|
+
async handleToolCallRequestV2(params) {
|
|
1071
|
+
if (!params || typeof params.sessionId !== "string" || typeof params.toolCallId !== "string" || typeof params.toolName !== "string") {
|
|
1072
|
+
throw new Error("Invalid tool call payload");
|
|
1073
|
+
}
|
|
1074
|
+
const session = this.sessions.get(params.sessionId);
|
|
1075
|
+
if (!session) {
|
|
1076
|
+
throw new Error(`Unknown session ${params.sessionId}`);
|
|
1077
|
+
}
|
|
1078
|
+
const handler = session.getToolHandler(params.toolName);
|
|
1079
|
+
if (!handler) {
|
|
1080
|
+
return {
|
|
1081
|
+
result: {
|
|
1082
|
+
textResultForLlm: `Tool '${params.toolName}' is not supported by this client instance.`,
|
|
1083
|
+
resultType: "failure",
|
|
1084
|
+
error: `tool '${params.toolName}' not supported`,
|
|
1085
|
+
toolTelemetry: {}
|
|
1086
|
+
}
|
|
1087
|
+
};
|
|
1088
|
+
}
|
|
1089
|
+
try {
|
|
1090
|
+
const invocation = {
|
|
1091
|
+
sessionId: params.sessionId,
|
|
1092
|
+
toolCallId: params.toolCallId,
|
|
1093
|
+
toolName: params.toolName,
|
|
1094
|
+
arguments: params.arguments
|
|
1095
|
+
};
|
|
1096
|
+
const result = await handler(params.arguments, invocation);
|
|
1097
|
+
return { result: this.normalizeToolResultV2(result) };
|
|
1098
|
+
} catch (error) {
|
|
1099
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1100
|
+
return {
|
|
1101
|
+
result: {
|
|
1102
|
+
textResultForLlm: "Invoking this tool produced an error. Detailed information is not available.",
|
|
1103
|
+
resultType: "failure",
|
|
1104
|
+
error: message,
|
|
1105
|
+
toolTelemetry: {}
|
|
1106
|
+
}
|
|
1107
|
+
};
|
|
1108
|
+
}
|
|
1109
|
+
}
|
|
1110
|
+
/**
|
|
1111
|
+
* Handles a v2-style permission.request RPC request from the server.
|
|
1112
|
+
*/
|
|
1113
|
+
async handlePermissionRequestV2(params) {
|
|
1114
|
+
if (!params || typeof params.sessionId !== "string" || !params.permissionRequest) {
|
|
1115
|
+
throw new Error("Invalid permission request payload");
|
|
1116
|
+
}
|
|
1117
|
+
const session = this.sessions.get(params.sessionId);
|
|
1118
|
+
if (!session) {
|
|
1119
|
+
throw new Error(`Session not found: ${params.sessionId}`);
|
|
1120
|
+
}
|
|
1121
|
+
try {
|
|
1122
|
+
const result = await session._handlePermissionRequestV2(params.permissionRequest);
|
|
1123
|
+
return { result };
|
|
1124
|
+
} catch (_error) {
|
|
1125
|
+
return {
|
|
1126
|
+
result: {
|
|
1127
|
+
kind: "denied-no-approval-rule-and-could-not-request-from-user"
|
|
1128
|
+
}
|
|
1129
|
+
};
|
|
1130
|
+
}
|
|
1131
|
+
}
|
|
1132
|
+
normalizeToolResultV2(result) {
|
|
1133
|
+
if (result === void 0 || result === null) {
|
|
1134
|
+
return {
|
|
1135
|
+
textResultForLlm: "Tool returned no result",
|
|
1136
|
+
resultType: "failure",
|
|
1137
|
+
error: "tool returned no result",
|
|
1138
|
+
toolTelemetry: {}
|
|
1139
|
+
};
|
|
1140
|
+
}
|
|
1141
|
+
if (this.isToolResultObject(result)) {
|
|
1142
|
+
return result;
|
|
1143
|
+
}
|
|
1144
|
+
const textResult = typeof result === "string" ? result : JSON.stringify(result);
|
|
1145
|
+
return {
|
|
1146
|
+
textResultForLlm: textResult,
|
|
1147
|
+
resultType: "success",
|
|
1148
|
+
toolTelemetry: {}
|
|
1149
|
+
};
|
|
1150
|
+
}
|
|
1151
|
+
isToolResultObject(value) {
|
|
1152
|
+
return typeof value === "object" && value !== null && "textResultForLlm" in value && typeof value.textResultForLlm === "string" && "resultType" in value;
|
|
1153
|
+
}
|
|
1044
1154
|
/**
|
|
1045
1155
|
* Attempt to reconnect to the server
|
|
1046
1156
|
*/
|
package/dist/generated/rpc.d.ts
CHANGED
|
@@ -407,7 +407,14 @@ export interface SessionToolsHandlePendingToolCallParams {
|
|
|
407
407
|
*/
|
|
408
408
|
sessionId: string;
|
|
409
409
|
requestId: string;
|
|
410
|
-
result?: string
|
|
410
|
+
result?: string | {
|
|
411
|
+
textResultForLlm: string;
|
|
412
|
+
resultType?: string;
|
|
413
|
+
error?: string;
|
|
414
|
+
toolTelemetry?: {
|
|
415
|
+
[k: string]: unknown;
|
|
416
|
+
};
|
|
417
|
+
};
|
|
411
418
|
error?: string;
|
|
412
419
|
}
|
|
413
420
|
export interface SessionPermissionsHandlePendingPermissionRequestResult {
|
|
@@ -420,8 +427,19 @@ export interface SessionPermissionsHandlePendingPermissionRequestParams {
|
|
|
420
427
|
sessionId: string;
|
|
421
428
|
requestId: string;
|
|
422
429
|
result: {
|
|
423
|
-
kind: "approved"
|
|
424
|
-
|
|
430
|
+
kind: "approved";
|
|
431
|
+
} | {
|
|
432
|
+
kind: "denied-by-rules";
|
|
433
|
+
rules: unknown[];
|
|
434
|
+
} | {
|
|
435
|
+
kind: "denied-no-approval-rule-and-could-not-request-from-user";
|
|
436
|
+
} | {
|
|
437
|
+
kind: "denied-interactively-by-user";
|
|
438
|
+
feedback?: string;
|
|
439
|
+
} | {
|
|
440
|
+
kind: "denied-by-content-exclusion-policy";
|
|
441
|
+
path: string;
|
|
442
|
+
message: string;
|
|
425
443
|
};
|
|
426
444
|
}
|
|
427
445
|
/** Create typed server-scoped RPC methods (no session required). */
|
package/dist/session.d.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import type { MessageConnection } from "vscode-jsonrpc/node";
|
|
6
6
|
import { createSessionRpc } from "./generated/rpc.js";
|
|
7
|
-
import type { MessageOptions, PermissionHandler, SessionEvent, SessionEventHandler, SessionEventType, SessionHooks, Tool, ToolHandler, TypedSessionEventHandler, UserInputHandler, UserInputResponse } from "./types.js";
|
|
7
|
+
import type { MessageOptions, PermissionHandler, PermissionRequestResult, SessionEvent, SessionEventHandler, SessionEventType, SessionHooks, Tool, ToolHandler, TypedSessionEventHandler, UserInputHandler, UserInputResponse } from "./types.js";
|
|
8
8
|
/** Assistant message event - the final response from the assistant. */
|
|
9
9
|
export type AssistantMessageEvent = Extract<SessionEvent, {
|
|
10
10
|
type: "assistant.message";
|
|
@@ -31,7 +31,7 @@ export type AssistantMessageEvent = Extract<SessionEvent, {
|
|
|
31
31
|
* await session.sendAndWait({ prompt: "Hello, world!" });
|
|
32
32
|
*
|
|
33
33
|
* // Clean up
|
|
34
|
-
* await session.
|
|
34
|
+
* await session.disconnect();
|
|
35
35
|
* ```
|
|
36
36
|
*/
|
|
37
37
|
export declare class CopilotSession {
|
|
@@ -72,7 +72,7 @@ export declare class CopilotSession {
|
|
|
72
72
|
*
|
|
73
73
|
* @param options - The message options including the prompt and optional attachments
|
|
74
74
|
* @returns A promise that resolves with the message ID of the response
|
|
75
|
-
* @throws Error if the session has been
|
|
75
|
+
* @throws Error if the session has been disconnected or the connection fails
|
|
76
76
|
*
|
|
77
77
|
* @example
|
|
78
78
|
* ```typescript
|
|
@@ -97,7 +97,7 @@ export declare class CopilotSession {
|
|
|
97
97
|
* @returns A promise that resolves with the final assistant message when the session becomes idle,
|
|
98
98
|
* or undefined if no assistant message was received
|
|
99
99
|
* @throws Error if the timeout is reached before the session becomes idle
|
|
100
|
-
* @throws Error if the session has been
|
|
100
|
+
* @throws Error if the session has been disconnected or the connection fails
|
|
101
101
|
*
|
|
102
102
|
* @example
|
|
103
103
|
* ```typescript
|
|
@@ -226,6 +226,15 @@ export declare class CopilotSession {
|
|
|
226
226
|
* @internal This method is typically called internally when creating a session.
|
|
227
227
|
*/
|
|
228
228
|
registerHooks(hooks?: SessionHooks): void;
|
|
229
|
+
/**
|
|
230
|
+
* Handles a permission request in the v2 protocol format (synchronous RPC).
|
|
231
|
+
* Used as a back-compat adapter when connected to a v2 server.
|
|
232
|
+
*
|
|
233
|
+
* @param request - The permission request data from the CLI
|
|
234
|
+
* @returns A promise that resolves with the permission decision
|
|
235
|
+
* @internal This method is for internal use by the SDK.
|
|
236
|
+
*/
|
|
237
|
+
_handlePermissionRequestV2(request: unknown): Promise<PermissionRequestResult>;
|
|
229
238
|
/**
|
|
230
239
|
* Handles a user input request from the Copilot CLI.
|
|
231
240
|
*
|
|
@@ -250,7 +259,7 @@ export declare class CopilotSession {
|
|
|
250
259
|
* assistant responses, tool executions, and other session events.
|
|
251
260
|
*
|
|
252
261
|
* @returns A promise that resolves with an array of all session events
|
|
253
|
-
* @throws Error if the session has been
|
|
262
|
+
* @throws Error if the session has been disconnected or the connection fails
|
|
254
263
|
*
|
|
255
264
|
* @example
|
|
256
265
|
* ```typescript
|
|
@@ -264,22 +273,39 @@ export declare class CopilotSession {
|
|
|
264
273
|
*/
|
|
265
274
|
getMessages(): Promise<SessionEvent[]>;
|
|
266
275
|
/**
|
|
267
|
-
*
|
|
276
|
+
* Disconnects this session and releases all in-memory resources (event handlers,
|
|
277
|
+
* tool handlers, permission handlers).
|
|
278
|
+
*
|
|
279
|
+
* Session state on disk (conversation history, planning state, artifacts) is
|
|
280
|
+
* preserved, so the conversation can be resumed later by calling
|
|
281
|
+
* {@link CopilotClient.resumeSession} with the session ID. To permanently
|
|
282
|
+
* remove all session data including files on disk, use
|
|
283
|
+
* {@link CopilotClient.deleteSession} instead.
|
|
268
284
|
*
|
|
269
|
-
* After calling this method, the session can no longer be used.
|
|
270
|
-
* handlers and tool handlers are cleared. To continue the conversation,
|
|
271
|
-
* use {@link CopilotClient.resumeSession} with the session ID.
|
|
285
|
+
* After calling this method, the session object can no longer be used.
|
|
272
286
|
*
|
|
273
|
-
* @returns A promise that resolves when the session is
|
|
287
|
+
* @returns A promise that resolves when the session is disconnected
|
|
274
288
|
* @throws Error if the connection fails
|
|
275
289
|
*
|
|
276
290
|
* @example
|
|
277
291
|
* ```typescript
|
|
278
|
-
* // Clean up when done
|
|
279
|
-
* await session.
|
|
292
|
+
* // Clean up when done — session can still be resumed later
|
|
293
|
+
* await session.disconnect();
|
|
280
294
|
* ```
|
|
281
295
|
*/
|
|
296
|
+
disconnect(): Promise<void>;
|
|
297
|
+
/**
|
|
298
|
+
* @deprecated Use {@link disconnect} instead. This method will be removed in a future release.
|
|
299
|
+
*
|
|
300
|
+
* Disconnects this session and releases all in-memory resources.
|
|
301
|
+
* Session data on disk is preserved for later resumption.
|
|
302
|
+
*
|
|
303
|
+
* @returns A promise that resolves when the session is disconnected
|
|
304
|
+
* @throws Error if the connection fails
|
|
305
|
+
*/
|
|
282
306
|
destroy(): Promise<void>;
|
|
307
|
+
/** Enables `await using session = ...` syntax for automatic cleanup. */
|
|
308
|
+
[Symbol.asyncDispose](): Promise<void>;
|
|
283
309
|
/**
|
|
284
310
|
* Aborts the currently processing message in this session.
|
|
285
311
|
*
|
|
@@ -287,7 +313,7 @@ export declare class CopilotSession {
|
|
|
287
313
|
* and can continue to be used for new messages.
|
|
288
314
|
*
|
|
289
315
|
* @returns A promise that resolves when the abort request is acknowledged
|
|
290
|
-
* @throws Error if the session has been
|
|
316
|
+
* @throws Error if the session has been disconnected or the connection fails
|
|
291
317
|
*
|
|
292
318
|
* @example
|
|
293
319
|
* ```typescript
|
package/dist/session.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ConnectionError, ResponseError } from "vscode-jsonrpc/node";
|
|
1
2
|
import { createSessionRpc } from "./generated/rpc.js";
|
|
2
3
|
class CopilotSession {
|
|
3
4
|
/**
|
|
@@ -45,7 +46,7 @@ class CopilotSession {
|
|
|
45
46
|
*
|
|
46
47
|
* @param options - The message options including the prompt and optional attachments
|
|
47
48
|
* @returns A promise that resolves with the message ID of the response
|
|
48
|
-
* @throws Error if the session has been
|
|
49
|
+
* @throws Error if the session has been disconnected or the connection fails
|
|
49
50
|
*
|
|
50
51
|
* @example
|
|
51
52
|
* ```typescript
|
|
@@ -78,7 +79,7 @@ class CopilotSession {
|
|
|
78
79
|
* @returns A promise that resolves with the final assistant message when the session becomes idle,
|
|
79
80
|
* or undefined if no assistant message was received
|
|
80
81
|
* @throws Error if the timeout is reached before the session becomes idle
|
|
81
|
-
* @throws Error if the session has been
|
|
82
|
+
* @throws Error if the session has been disconnected or the connection fails
|
|
82
83
|
*
|
|
83
84
|
* @example
|
|
84
85
|
* ```typescript
|
|
@@ -220,7 +221,13 @@ class CopilotSession {
|
|
|
220
221
|
await this.rpc.tools.handlePendingToolCall({ requestId, result });
|
|
221
222
|
} catch (error) {
|
|
222
223
|
const message = error instanceof Error ? error.message : String(error);
|
|
223
|
-
|
|
224
|
+
try {
|
|
225
|
+
await this.rpc.tools.handlePendingToolCall({ requestId, error: message });
|
|
226
|
+
} catch (rpcError) {
|
|
227
|
+
if (!(rpcError instanceof ConnectionError || rpcError instanceof ResponseError)) {
|
|
228
|
+
throw rpcError;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
224
231
|
}
|
|
225
232
|
}
|
|
226
233
|
/**
|
|
@@ -234,12 +241,18 @@ class CopilotSession {
|
|
|
234
241
|
});
|
|
235
242
|
await this.rpc.permissions.handlePendingPermissionRequest({ requestId, result });
|
|
236
243
|
} catch (_error) {
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
244
|
+
try {
|
|
245
|
+
await this.rpc.permissions.handlePendingPermissionRequest({
|
|
246
|
+
requestId,
|
|
247
|
+
result: {
|
|
248
|
+
kind: "denied-no-approval-rule-and-could-not-request-from-user"
|
|
249
|
+
}
|
|
250
|
+
});
|
|
251
|
+
} catch (rpcError) {
|
|
252
|
+
if (!(rpcError instanceof ConnectionError || rpcError instanceof ResponseError)) {
|
|
253
|
+
throw rpcError;
|
|
241
254
|
}
|
|
242
|
-
}
|
|
255
|
+
}
|
|
243
256
|
}
|
|
244
257
|
}
|
|
245
258
|
/**
|
|
@@ -306,6 +319,27 @@ class CopilotSession {
|
|
|
306
319
|
registerHooks(hooks) {
|
|
307
320
|
this.hooks = hooks;
|
|
308
321
|
}
|
|
322
|
+
/**
|
|
323
|
+
* Handles a permission request in the v2 protocol format (synchronous RPC).
|
|
324
|
+
* Used as a back-compat adapter when connected to a v2 server.
|
|
325
|
+
*
|
|
326
|
+
* @param request - The permission request data from the CLI
|
|
327
|
+
* @returns A promise that resolves with the permission decision
|
|
328
|
+
* @internal This method is for internal use by the SDK.
|
|
329
|
+
*/
|
|
330
|
+
async _handlePermissionRequestV2(request) {
|
|
331
|
+
if (!this.permissionHandler) {
|
|
332
|
+
return { kind: "denied-no-approval-rule-and-could-not-request-from-user" };
|
|
333
|
+
}
|
|
334
|
+
try {
|
|
335
|
+
const result = await this.permissionHandler(request, {
|
|
336
|
+
sessionId: this.sessionId
|
|
337
|
+
});
|
|
338
|
+
return result;
|
|
339
|
+
} catch (_error) {
|
|
340
|
+
return { kind: "denied-no-approval-rule-and-could-not-request-from-user" };
|
|
341
|
+
}
|
|
342
|
+
}
|
|
309
343
|
/**
|
|
310
344
|
* Handles a user input request from the Copilot CLI.
|
|
311
345
|
*
|
|
@@ -364,7 +398,7 @@ class CopilotSession {
|
|
|
364
398
|
* assistant responses, tool executions, and other session events.
|
|
365
399
|
*
|
|
366
400
|
* @returns A promise that resolves with an array of all session events
|
|
367
|
-
* @throws Error if the session has been
|
|
401
|
+
* @throws Error if the session has been disconnected or the connection fails
|
|
368
402
|
*
|
|
369
403
|
* @example
|
|
370
404
|
* ```typescript
|
|
@@ -383,22 +417,27 @@ class CopilotSession {
|
|
|
383
417
|
return response.events;
|
|
384
418
|
}
|
|
385
419
|
/**
|
|
386
|
-
*
|
|
420
|
+
* Disconnects this session and releases all in-memory resources (event handlers,
|
|
421
|
+
* tool handlers, permission handlers).
|
|
387
422
|
*
|
|
388
|
-
*
|
|
389
|
-
*
|
|
390
|
-
*
|
|
423
|
+
* Session state on disk (conversation history, planning state, artifacts) is
|
|
424
|
+
* preserved, so the conversation can be resumed later by calling
|
|
425
|
+
* {@link CopilotClient.resumeSession} with the session ID. To permanently
|
|
426
|
+
* remove all session data including files on disk, use
|
|
427
|
+
* {@link CopilotClient.deleteSession} instead.
|
|
391
428
|
*
|
|
392
|
-
*
|
|
429
|
+
* After calling this method, the session object can no longer be used.
|
|
430
|
+
*
|
|
431
|
+
* @returns A promise that resolves when the session is disconnected
|
|
393
432
|
* @throws Error if the connection fails
|
|
394
433
|
*
|
|
395
434
|
* @example
|
|
396
435
|
* ```typescript
|
|
397
|
-
* // Clean up when done
|
|
398
|
-
* await session.
|
|
436
|
+
* // Clean up when done — session can still be resumed later
|
|
437
|
+
* await session.disconnect();
|
|
399
438
|
* ```
|
|
400
439
|
*/
|
|
401
|
-
async
|
|
440
|
+
async disconnect() {
|
|
402
441
|
await this.connection.sendRequest("session.destroy", {
|
|
403
442
|
sessionId: this.sessionId
|
|
404
443
|
});
|
|
@@ -407,6 +446,22 @@ class CopilotSession {
|
|
|
407
446
|
this.toolHandlers.clear();
|
|
408
447
|
this.permissionHandler = void 0;
|
|
409
448
|
}
|
|
449
|
+
/**
|
|
450
|
+
* @deprecated Use {@link disconnect} instead. This method will be removed in a future release.
|
|
451
|
+
*
|
|
452
|
+
* Disconnects this session and releases all in-memory resources.
|
|
453
|
+
* Session data on disk is preserved for later resumption.
|
|
454
|
+
*
|
|
455
|
+
* @returns A promise that resolves when the session is disconnected
|
|
456
|
+
* @throws Error if the connection fails
|
|
457
|
+
*/
|
|
458
|
+
async destroy() {
|
|
459
|
+
return this.disconnect();
|
|
460
|
+
}
|
|
461
|
+
/** Enables `await using session = ...` syntax for automatic cleanup. */
|
|
462
|
+
async [Symbol.asyncDispose]() {
|
|
463
|
+
return this.disconnect();
|
|
464
|
+
}
|
|
410
465
|
/**
|
|
411
466
|
* Aborts the currently processing message in this session.
|
|
412
467
|
*
|
|
@@ -414,7 +469,7 @@ class CopilotSession {
|
|
|
414
469
|
* and can continue to be used for new messages.
|
|
415
470
|
*
|
|
416
471
|
* @returns A promise that resolves when the abort request is acknowledged
|
|
417
|
-
* @throws Error if the session has been
|
|
472
|
+
* @throws Error if the session has been disconnected or the connection fails
|
|
418
473
|
*
|
|
419
474
|
* @example
|
|
420
475
|
* ```typescript
|
package/dist/types.d.ts
CHANGED
|
@@ -185,10 +185,8 @@ export interface PermissionRequest {
|
|
|
185
185
|
toolCallId?: string;
|
|
186
186
|
[key: string]: unknown;
|
|
187
187
|
}
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
rules?: unknown[];
|
|
191
|
-
}
|
|
188
|
+
import type { SessionPermissionsHandlePendingPermissionRequestParams } from "./generated/rpc.js";
|
|
189
|
+
export type PermissionRequestResult = SessionPermissionsHandlePendingPermissionRequestParams["result"];
|
|
192
190
|
export type PermissionHandler = (request: PermissionRequest, invocation: {
|
|
193
191
|
sessionId: string;
|
|
194
192
|
}) => Promise<PermissionRequestResult> | PermissionRequestResult;
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"type": "git",
|
|
5
5
|
"url": "https://github.com/github/copilot-sdk.git"
|
|
6
6
|
},
|
|
7
|
-
"version": "0.1.
|
|
7
|
+
"version": "0.1.32",
|
|
8
8
|
"description": "TypeScript SDK for programmatic control of GitHub Copilot CLI via JSON-RPC",
|
|
9
9
|
"main": "./dist/index.js",
|
|
10
10
|
"types": "./dist/index.d.ts",
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"author": "GitHub",
|
|
45
45
|
"license": "MIT",
|
|
46
46
|
"dependencies": {
|
|
47
|
-
"@github/copilot": "^
|
|
47
|
+
"@github/copilot": "^1.0.2",
|
|
48
48
|
"vscode-jsonrpc": "^8.2.1",
|
|
49
49
|
"zod": "^4.3.6"
|
|
50
50
|
},
|