@github/copilot-sdk 0.1.10-preview.1 → 0.1.11
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/dist/client.js +213 -17
- package/dist/nodejs/src/client.d.ts +306 -0
- package/dist/{generated → nodejs/src/generated}/session-events.d.ts +8 -1
- package/dist/nodejs/src/index.d.ts +9 -0
- package/dist/nodejs/src/sdkProtocolVersion.d.ts +5 -0
- package/dist/nodejs/src/session.d.ts +194 -0
- package/dist/{types.d.ts → nodejs/src/types.d.ts} +95 -1
- package/dist/sdkProtocolVersion.js +7 -0
- package/dist/session.js +132 -7
- package/package.json +4 -3
- package/dist/client.d.ts +0 -96
- package/dist/index.d.ts +0 -9
- package/dist/session.d.ts +0 -42
package/dist/client.js
CHANGED
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
StreamMessageWriter
|
|
7
7
|
} from "vscode-jsonrpc/node.js";
|
|
8
8
|
import { CopilotSession } from "./session.js";
|
|
9
|
+
import { getSdkProtocolVersion } from "./sdkProtocolVersion.js";
|
|
9
10
|
function isZodSchema(value) {
|
|
10
11
|
return value != null && typeof value === "object" && "toJSONSchema" in value && typeof value.toJSONSchema === "function";
|
|
11
12
|
}
|
|
@@ -27,6 +28,27 @@ class CopilotClient {
|
|
|
27
28
|
options;
|
|
28
29
|
isExternalServer = false;
|
|
29
30
|
forceStopping = false;
|
|
31
|
+
/**
|
|
32
|
+
* Creates a new CopilotClient instance.
|
|
33
|
+
*
|
|
34
|
+
* @param options - Configuration options for the client
|
|
35
|
+
* @throws Error if mutually exclusive options are provided (e.g., cliUrl with useStdio or cliPath)
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```typescript
|
|
39
|
+
* // Default options - spawns CLI server using stdio
|
|
40
|
+
* const client = new CopilotClient();
|
|
41
|
+
*
|
|
42
|
+
* // Connect to an existing server
|
|
43
|
+
* const client = new CopilotClient({ cliUrl: "localhost:3000" });
|
|
44
|
+
*
|
|
45
|
+
* // Custom CLI path with specific log level
|
|
46
|
+
* const client = new CopilotClient({
|
|
47
|
+
* cliPath: "/usr/local/bin/copilot",
|
|
48
|
+
* logLevel: "debug"
|
|
49
|
+
* });
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
30
52
|
constructor(options = {}) {
|
|
31
53
|
if (options.cliUrl && (options.useStdio === true || options.cliPath)) {
|
|
32
54
|
throw new Error("cliUrl is mutually exclusive with useStdio and cliPath");
|
|
@@ -74,7 +96,22 @@ class CopilotClient {
|
|
|
74
96
|
return { host, port };
|
|
75
97
|
}
|
|
76
98
|
/**
|
|
77
|
-
*
|
|
99
|
+
* Starts the CLI server and establishes a connection.
|
|
100
|
+
*
|
|
101
|
+
* If connecting to an external server (via cliUrl), only establishes the connection.
|
|
102
|
+
* Otherwise, spawns the CLI server process and then connects.
|
|
103
|
+
*
|
|
104
|
+
* This method is called automatically when creating a session if `autoStart` is true (default).
|
|
105
|
+
*
|
|
106
|
+
* @returns A promise that resolves when the connection is established
|
|
107
|
+
* @throws Error if the server fails to start or the connection fails
|
|
108
|
+
*
|
|
109
|
+
* @example
|
|
110
|
+
* ```typescript
|
|
111
|
+
* const client = new CopilotClient({ autoStart: false });
|
|
112
|
+
* await client.start();
|
|
113
|
+
* // Now ready to create sessions
|
|
114
|
+
* ```
|
|
78
115
|
*/
|
|
79
116
|
async start() {
|
|
80
117
|
if (this.state === "connected") {
|
|
@@ -86,6 +123,7 @@ class CopilotClient {
|
|
|
86
123
|
await this.startCLIServer();
|
|
87
124
|
}
|
|
88
125
|
await this.connectToServer();
|
|
126
|
+
await this.verifyProtocolVersion();
|
|
89
127
|
this.state = "connected";
|
|
90
128
|
} catch (error) {
|
|
91
129
|
this.state = "error";
|
|
@@ -93,8 +131,23 @@ class CopilotClient {
|
|
|
93
131
|
}
|
|
94
132
|
}
|
|
95
133
|
/**
|
|
96
|
-
*
|
|
97
|
-
*
|
|
134
|
+
* Stops the CLI server and closes all active sessions.
|
|
135
|
+
*
|
|
136
|
+
* This method performs graceful cleanup:
|
|
137
|
+
* 1. Destroys all active sessions with retry logic
|
|
138
|
+
* 2. Closes the JSON-RPC connection
|
|
139
|
+
* 3. Terminates the CLI server process (if spawned by this client)
|
|
140
|
+
*
|
|
141
|
+
* @returns A promise that resolves with an array of errors encountered during cleanup.
|
|
142
|
+
* An empty array indicates all cleanup succeeded.
|
|
143
|
+
*
|
|
144
|
+
* @example
|
|
145
|
+
* ```typescript
|
|
146
|
+
* const errors = await client.stop();
|
|
147
|
+
* if (errors.length > 0) {
|
|
148
|
+
* console.error("Cleanup errors:", errors);
|
|
149
|
+
* }
|
|
150
|
+
* ```
|
|
98
151
|
*/
|
|
99
152
|
async stop() {
|
|
100
153
|
const errors = [];
|
|
@@ -164,8 +217,29 @@ class CopilotClient {
|
|
|
164
217
|
return errors;
|
|
165
218
|
}
|
|
166
219
|
/**
|
|
167
|
-
*
|
|
168
|
-
*
|
|
220
|
+
* Forcefully stops the CLI server without graceful cleanup.
|
|
221
|
+
*
|
|
222
|
+
* Use this when {@link stop} fails or takes too long. This method:
|
|
223
|
+
* - Clears all sessions immediately without destroying them
|
|
224
|
+
* - Force closes the connection
|
|
225
|
+
* - Sends SIGKILL to the CLI process (if spawned by this client)
|
|
226
|
+
*
|
|
227
|
+
* @returns A promise that resolves when the force stop is complete
|
|
228
|
+
*
|
|
229
|
+
* @example
|
|
230
|
+
* ```typescript
|
|
231
|
+
* // If normal stop hangs, force stop
|
|
232
|
+
* const stopPromise = client.stop();
|
|
233
|
+
* const timeout = new Promise((_, reject) =>
|
|
234
|
+
* setTimeout(() => reject(new Error("Timeout")), 5000)
|
|
235
|
+
* );
|
|
236
|
+
*
|
|
237
|
+
* try {
|
|
238
|
+
* await Promise.race([stopPromise, timeout]);
|
|
239
|
+
* } catch {
|
|
240
|
+
* await client.forceStop();
|
|
241
|
+
* }
|
|
242
|
+
* ```
|
|
169
243
|
*/
|
|
170
244
|
async forceStop() {
|
|
171
245
|
this.forceStopping = true;
|
|
@@ -195,7 +269,32 @@ class CopilotClient {
|
|
|
195
269
|
this.actualPort = null;
|
|
196
270
|
}
|
|
197
271
|
/**
|
|
198
|
-
*
|
|
272
|
+
* Creates a new conversation session with the Copilot CLI.
|
|
273
|
+
*
|
|
274
|
+
* Sessions maintain conversation state, handle events, and manage tool execution.
|
|
275
|
+
* If the client is not connected and `autoStart` is enabled, this will automatically
|
|
276
|
+
* start the connection.
|
|
277
|
+
*
|
|
278
|
+
* @param config - Optional configuration for the session
|
|
279
|
+
* @returns A promise that resolves with the created session
|
|
280
|
+
* @throws Error if the client is not connected and autoStart is disabled
|
|
281
|
+
*
|
|
282
|
+
* @example
|
|
283
|
+
* ```typescript
|
|
284
|
+
* // Basic session
|
|
285
|
+
* const session = await client.createSession();
|
|
286
|
+
*
|
|
287
|
+
* // Session with model and tools
|
|
288
|
+
* const session = await client.createSession({
|
|
289
|
+
* model: "gpt-4",
|
|
290
|
+
* tools: [{
|
|
291
|
+
* name: "get_weather",
|
|
292
|
+
* description: "Get weather for a location",
|
|
293
|
+
* parameters: { type: "object", properties: { location: { type: "string" } } },
|
|
294
|
+
* handler: async (args) => ({ temperature: 72 })
|
|
295
|
+
* }]
|
|
296
|
+
* });
|
|
297
|
+
* ```
|
|
199
298
|
*/
|
|
200
299
|
async createSession(config = {}) {
|
|
201
300
|
if (!this.connection) {
|
|
@@ -218,7 +317,9 @@ class CopilotClient {
|
|
|
218
317
|
excludedTools: config.excludedTools,
|
|
219
318
|
provider: config.provider,
|
|
220
319
|
requestPermission: !!config.onPermissionRequest,
|
|
221
|
-
streaming: config.streaming
|
|
320
|
+
streaming: config.streaming,
|
|
321
|
+
mcpServers: config.mcpServers,
|
|
322
|
+
customAgents: config.customAgents
|
|
222
323
|
});
|
|
223
324
|
const sessionId = response.sessionId;
|
|
224
325
|
const session = new CopilotSession(sessionId, this.connection);
|
|
@@ -230,7 +331,27 @@ class CopilotClient {
|
|
|
230
331
|
return session;
|
|
231
332
|
}
|
|
232
333
|
/**
|
|
233
|
-
*
|
|
334
|
+
* Resumes an existing conversation session by its ID.
|
|
335
|
+
*
|
|
336
|
+
* This allows you to continue a previous conversation, maintaining all
|
|
337
|
+
* conversation history. The session must have been previously created
|
|
338
|
+
* and not deleted.
|
|
339
|
+
*
|
|
340
|
+
* @param sessionId - The ID of the session to resume
|
|
341
|
+
* @param config - Optional configuration for the resumed session
|
|
342
|
+
* @returns A promise that resolves with the resumed session
|
|
343
|
+
* @throws Error if the session does not exist or the client is not connected
|
|
344
|
+
*
|
|
345
|
+
* @example
|
|
346
|
+
* ```typescript
|
|
347
|
+
* // Resume a previous session
|
|
348
|
+
* const session = await client.resumeSession("session-123");
|
|
349
|
+
*
|
|
350
|
+
* // Resume with new tools
|
|
351
|
+
* const session = await client.resumeSession("session-123", {
|
|
352
|
+
* tools: [myNewTool]
|
|
353
|
+
* });
|
|
354
|
+
* ```
|
|
234
355
|
*/
|
|
235
356
|
async resumeSession(sessionId, config = {}) {
|
|
236
357
|
if (!this.connection) {
|
|
@@ -249,7 +370,9 @@ class CopilotClient {
|
|
|
249
370
|
})),
|
|
250
371
|
provider: config.provider,
|
|
251
372
|
requestPermission: !!config.onPermissionRequest,
|
|
252
|
-
streaming: config.streaming
|
|
373
|
+
streaming: config.streaming,
|
|
374
|
+
mcpServers: config.mcpServers,
|
|
375
|
+
customAgents: config.customAgents
|
|
253
376
|
});
|
|
254
377
|
const resumedSessionId = response.sessionId;
|
|
255
378
|
const session = new CopilotSession(resumedSessionId, this.connection);
|
|
@@ -261,13 +384,32 @@ class CopilotClient {
|
|
|
261
384
|
return session;
|
|
262
385
|
}
|
|
263
386
|
/**
|
|
264
|
-
*
|
|
387
|
+
* Gets the current connection state of the client.
|
|
388
|
+
*
|
|
389
|
+
* @returns The current connection state: "disconnected", "connecting", "connected", or "error"
|
|
390
|
+
*
|
|
391
|
+
* @example
|
|
392
|
+
* ```typescript
|
|
393
|
+
* if (client.getState() === "connected") {
|
|
394
|
+
* const session = await client.createSession();
|
|
395
|
+
* }
|
|
396
|
+
* ```
|
|
265
397
|
*/
|
|
266
398
|
getState() {
|
|
267
399
|
return this.state;
|
|
268
400
|
}
|
|
269
401
|
/**
|
|
270
|
-
*
|
|
402
|
+
* Sends a ping request to the server to verify connectivity.
|
|
403
|
+
*
|
|
404
|
+
* @param message - Optional message to include in the ping
|
|
405
|
+
* @returns A promise that resolves with the ping response containing the message and timestamp
|
|
406
|
+
* @throws Error if the client is not connected
|
|
407
|
+
*
|
|
408
|
+
* @example
|
|
409
|
+
* ```typescript
|
|
410
|
+
* const response = await client.ping("health check");
|
|
411
|
+
* console.log(`Server responded at ${new Date(response.timestamp)}`);
|
|
412
|
+
* ```
|
|
271
413
|
*/
|
|
272
414
|
async ping(message) {
|
|
273
415
|
if (!this.connection) {
|
|
@@ -277,8 +419,39 @@ class CopilotClient {
|
|
|
277
419
|
return result;
|
|
278
420
|
}
|
|
279
421
|
/**
|
|
280
|
-
*
|
|
281
|
-
|
|
422
|
+
* Verify that the server's protocol version matches the SDK's expected version
|
|
423
|
+
*/
|
|
424
|
+
async verifyProtocolVersion() {
|
|
425
|
+
const expectedVersion = getSdkProtocolVersion();
|
|
426
|
+
const pingResult = await this.ping();
|
|
427
|
+
const serverVersion = pingResult.protocolVersion;
|
|
428
|
+
if (serverVersion === void 0) {
|
|
429
|
+
throw new Error(
|
|
430
|
+
`SDK protocol version mismatch: SDK expects version ${expectedVersion}, but server does not report a protocol version. Please update your server to ensure compatibility.`
|
|
431
|
+
);
|
|
432
|
+
}
|
|
433
|
+
if (serverVersion !== expectedVersion) {
|
|
434
|
+
throw new Error(
|
|
435
|
+
`SDK protocol version mismatch: SDK expects version ${expectedVersion}, but server reports version ${serverVersion}. Please update your SDK or server to ensure compatibility.`
|
|
436
|
+
);
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
/**
|
|
440
|
+
* Gets the ID of the most recently updated session.
|
|
441
|
+
*
|
|
442
|
+
* This is useful for resuming the last conversation when the session ID
|
|
443
|
+
* was not stored.
|
|
444
|
+
*
|
|
445
|
+
* @returns A promise that resolves with the session ID, or undefined if no sessions exist
|
|
446
|
+
* @throws Error if the client is not connected
|
|
447
|
+
*
|
|
448
|
+
* @example
|
|
449
|
+
* ```typescript
|
|
450
|
+
* const lastId = await client.getLastSessionId();
|
|
451
|
+
* if (lastId) {
|
|
452
|
+
* const session = await client.resumeSession(lastId);
|
|
453
|
+
* }
|
|
454
|
+
* ```
|
|
282
455
|
*/
|
|
283
456
|
async getLastSessionId() {
|
|
284
457
|
if (!this.connection) {
|
|
@@ -288,8 +461,19 @@ class CopilotClient {
|
|
|
288
461
|
return response.sessionId;
|
|
289
462
|
}
|
|
290
463
|
/**
|
|
291
|
-
*
|
|
292
|
-
*
|
|
464
|
+
* Deletes a session and its data from disk.
|
|
465
|
+
*
|
|
466
|
+
* This permanently removes the session and all its conversation history.
|
|
467
|
+
* The session cannot be resumed after deletion.
|
|
468
|
+
*
|
|
469
|
+
* @param sessionId - The ID of the session to delete
|
|
470
|
+
* @returns A promise that resolves when the session is deleted
|
|
471
|
+
* @throws Error if the session does not exist or deletion fails
|
|
472
|
+
*
|
|
473
|
+
* @example
|
|
474
|
+
* ```typescript
|
|
475
|
+
* await client.deleteSession("session-123");
|
|
476
|
+
* ```
|
|
293
477
|
*/
|
|
294
478
|
async deleteSession(sessionId) {
|
|
295
479
|
if (!this.connection) {
|
|
@@ -305,8 +489,20 @@ class CopilotClient {
|
|
|
305
489
|
this.sessions.delete(sessionId);
|
|
306
490
|
}
|
|
307
491
|
/**
|
|
308
|
-
*
|
|
309
|
-
*
|
|
492
|
+
* Lists all available sessions known to the server.
|
|
493
|
+
*
|
|
494
|
+
* Returns metadata about each session including ID, timestamps, and summary.
|
|
495
|
+
*
|
|
496
|
+
* @returns A promise that resolves with an array of session metadata
|
|
497
|
+
* @throws Error if the client is not connected
|
|
498
|
+
*
|
|
499
|
+
* @example
|
|
500
|
+
* ```typescript
|
|
501
|
+
* const sessions = await client.listSessions();
|
|
502
|
+
* for (const session of sessions) {
|
|
503
|
+
* console.log(`${session.sessionId}: ${session.summary}`);
|
|
504
|
+
* }
|
|
505
|
+
* ```
|
|
310
506
|
*/
|
|
311
507
|
async listSessions() {
|
|
312
508
|
if (!this.connection) {
|
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
import { CopilotSession } from "./session.js";
|
|
2
|
+
import type { ConnectionState, CopilotClientOptions, ResumeSessionConfig, SessionConfig, SessionMetadata } from "./types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Main client for interacting with the Copilot CLI.
|
|
5
|
+
*
|
|
6
|
+
* The CopilotClient manages the connection to the Copilot CLI server and provides
|
|
7
|
+
* methods to create and manage conversation sessions. It can either spawn a CLI
|
|
8
|
+
* server process or connect to an existing server.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```typescript
|
|
12
|
+
* import { CopilotClient } from "@github/copilot-sdk";
|
|
13
|
+
*
|
|
14
|
+
* // Create a client with default options (spawns CLI server)
|
|
15
|
+
* const client = new CopilotClient();
|
|
16
|
+
*
|
|
17
|
+
* // Or connect to an existing server
|
|
18
|
+
* const client = new CopilotClient({ cliUrl: "localhost:3000" });
|
|
19
|
+
*
|
|
20
|
+
* // Create a session
|
|
21
|
+
* const session = await client.createSession({ model: "gpt-4" });
|
|
22
|
+
*
|
|
23
|
+
* // Send messages and handle responses
|
|
24
|
+
* session.on((event) => {
|
|
25
|
+
* if (event.type === "assistant.message") {
|
|
26
|
+
* console.log(event.data.content);
|
|
27
|
+
* }
|
|
28
|
+
* });
|
|
29
|
+
* await session.send({ prompt: "Hello!" });
|
|
30
|
+
*
|
|
31
|
+
* // Clean up
|
|
32
|
+
* await session.destroy();
|
|
33
|
+
* await client.stop();
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export declare class CopilotClient {
|
|
37
|
+
private cliProcess;
|
|
38
|
+
private connection;
|
|
39
|
+
private socket;
|
|
40
|
+
private actualPort;
|
|
41
|
+
private actualHost;
|
|
42
|
+
private state;
|
|
43
|
+
private sessions;
|
|
44
|
+
private options;
|
|
45
|
+
private isExternalServer;
|
|
46
|
+
private forceStopping;
|
|
47
|
+
/**
|
|
48
|
+
* Creates a new CopilotClient instance.
|
|
49
|
+
*
|
|
50
|
+
* @param options - Configuration options for the client
|
|
51
|
+
* @throws Error if mutually exclusive options are provided (e.g., cliUrl with useStdio or cliPath)
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* ```typescript
|
|
55
|
+
* // Default options - spawns CLI server using stdio
|
|
56
|
+
* const client = new CopilotClient();
|
|
57
|
+
*
|
|
58
|
+
* // Connect to an existing server
|
|
59
|
+
* const client = new CopilotClient({ cliUrl: "localhost:3000" });
|
|
60
|
+
*
|
|
61
|
+
* // Custom CLI path with specific log level
|
|
62
|
+
* const client = new CopilotClient({
|
|
63
|
+
* cliPath: "/usr/local/bin/copilot",
|
|
64
|
+
* logLevel: "debug"
|
|
65
|
+
* });
|
|
66
|
+
* ```
|
|
67
|
+
*/
|
|
68
|
+
constructor(options?: CopilotClientOptions);
|
|
69
|
+
/**
|
|
70
|
+
* Parse CLI URL into host and port
|
|
71
|
+
* Supports formats: "host:port", "http://host:port", "https://host:port", or just "port"
|
|
72
|
+
*/
|
|
73
|
+
private parseCliUrl;
|
|
74
|
+
/**
|
|
75
|
+
* Starts the CLI server and establishes a connection.
|
|
76
|
+
*
|
|
77
|
+
* If connecting to an external server (via cliUrl), only establishes the connection.
|
|
78
|
+
* Otherwise, spawns the CLI server process and then connects.
|
|
79
|
+
*
|
|
80
|
+
* This method is called automatically when creating a session if `autoStart` is true (default).
|
|
81
|
+
*
|
|
82
|
+
* @returns A promise that resolves when the connection is established
|
|
83
|
+
* @throws Error if the server fails to start or the connection fails
|
|
84
|
+
*
|
|
85
|
+
* @example
|
|
86
|
+
* ```typescript
|
|
87
|
+
* const client = new CopilotClient({ autoStart: false });
|
|
88
|
+
* await client.start();
|
|
89
|
+
* // Now ready to create sessions
|
|
90
|
+
* ```
|
|
91
|
+
*/
|
|
92
|
+
start(): Promise<void>;
|
|
93
|
+
/**
|
|
94
|
+
* Stops the CLI server and closes all active sessions.
|
|
95
|
+
*
|
|
96
|
+
* This method performs graceful cleanup:
|
|
97
|
+
* 1. Destroys all active sessions with retry logic
|
|
98
|
+
* 2. Closes the JSON-RPC connection
|
|
99
|
+
* 3. Terminates the CLI server process (if spawned by this client)
|
|
100
|
+
*
|
|
101
|
+
* @returns A promise that resolves with an array of errors encountered during cleanup.
|
|
102
|
+
* An empty array indicates all cleanup succeeded.
|
|
103
|
+
*
|
|
104
|
+
* @example
|
|
105
|
+
* ```typescript
|
|
106
|
+
* const errors = await client.stop();
|
|
107
|
+
* if (errors.length > 0) {
|
|
108
|
+
* console.error("Cleanup errors:", errors);
|
|
109
|
+
* }
|
|
110
|
+
* ```
|
|
111
|
+
*/
|
|
112
|
+
stop(): Promise<Error[]>;
|
|
113
|
+
/**
|
|
114
|
+
* Forcefully stops the CLI server without graceful cleanup.
|
|
115
|
+
*
|
|
116
|
+
* Use this when {@link stop} fails or takes too long. This method:
|
|
117
|
+
* - Clears all sessions immediately without destroying them
|
|
118
|
+
* - Force closes the connection
|
|
119
|
+
* - Sends SIGKILL to the CLI process (if spawned by this client)
|
|
120
|
+
*
|
|
121
|
+
* @returns A promise that resolves when the force stop is complete
|
|
122
|
+
*
|
|
123
|
+
* @example
|
|
124
|
+
* ```typescript
|
|
125
|
+
* // If normal stop hangs, force stop
|
|
126
|
+
* const stopPromise = client.stop();
|
|
127
|
+
* const timeout = new Promise((_, reject) =>
|
|
128
|
+
* setTimeout(() => reject(new Error("Timeout")), 5000)
|
|
129
|
+
* );
|
|
130
|
+
*
|
|
131
|
+
* try {
|
|
132
|
+
* await Promise.race([stopPromise, timeout]);
|
|
133
|
+
* } catch {
|
|
134
|
+
* await client.forceStop();
|
|
135
|
+
* }
|
|
136
|
+
* ```
|
|
137
|
+
*/
|
|
138
|
+
forceStop(): Promise<void>;
|
|
139
|
+
/**
|
|
140
|
+
* Creates a new conversation session with the Copilot CLI.
|
|
141
|
+
*
|
|
142
|
+
* Sessions maintain conversation state, handle events, and manage tool execution.
|
|
143
|
+
* If the client is not connected and `autoStart` is enabled, this will automatically
|
|
144
|
+
* start the connection.
|
|
145
|
+
*
|
|
146
|
+
* @param config - Optional configuration for the session
|
|
147
|
+
* @returns A promise that resolves with the created session
|
|
148
|
+
* @throws Error if the client is not connected and autoStart is disabled
|
|
149
|
+
*
|
|
150
|
+
* @example
|
|
151
|
+
* ```typescript
|
|
152
|
+
* // Basic session
|
|
153
|
+
* const session = await client.createSession();
|
|
154
|
+
*
|
|
155
|
+
* // Session with model and tools
|
|
156
|
+
* const session = await client.createSession({
|
|
157
|
+
* model: "gpt-4",
|
|
158
|
+
* tools: [{
|
|
159
|
+
* name: "get_weather",
|
|
160
|
+
* description: "Get weather for a location",
|
|
161
|
+
* parameters: { type: "object", properties: { location: { type: "string" } } },
|
|
162
|
+
* handler: async (args) => ({ temperature: 72 })
|
|
163
|
+
* }]
|
|
164
|
+
* });
|
|
165
|
+
* ```
|
|
166
|
+
*/
|
|
167
|
+
createSession(config?: SessionConfig): Promise<CopilotSession>;
|
|
168
|
+
/**
|
|
169
|
+
* Resumes an existing conversation session by its ID.
|
|
170
|
+
*
|
|
171
|
+
* This allows you to continue a previous conversation, maintaining all
|
|
172
|
+
* conversation history. The session must have been previously created
|
|
173
|
+
* and not deleted.
|
|
174
|
+
*
|
|
175
|
+
* @param sessionId - The ID of the session to resume
|
|
176
|
+
* @param config - Optional configuration for the resumed session
|
|
177
|
+
* @returns A promise that resolves with the resumed session
|
|
178
|
+
* @throws Error if the session does not exist or the client is not connected
|
|
179
|
+
*
|
|
180
|
+
* @example
|
|
181
|
+
* ```typescript
|
|
182
|
+
* // Resume a previous session
|
|
183
|
+
* const session = await client.resumeSession("session-123");
|
|
184
|
+
*
|
|
185
|
+
* // Resume with new tools
|
|
186
|
+
* const session = await client.resumeSession("session-123", {
|
|
187
|
+
* tools: [myNewTool]
|
|
188
|
+
* });
|
|
189
|
+
* ```
|
|
190
|
+
*/
|
|
191
|
+
resumeSession(sessionId: string, config?: ResumeSessionConfig): Promise<CopilotSession>;
|
|
192
|
+
/**
|
|
193
|
+
* Gets the current connection state of the client.
|
|
194
|
+
*
|
|
195
|
+
* @returns The current connection state: "disconnected", "connecting", "connected", or "error"
|
|
196
|
+
*
|
|
197
|
+
* @example
|
|
198
|
+
* ```typescript
|
|
199
|
+
* if (client.getState() === "connected") {
|
|
200
|
+
* const session = await client.createSession();
|
|
201
|
+
* }
|
|
202
|
+
* ```
|
|
203
|
+
*/
|
|
204
|
+
getState(): ConnectionState;
|
|
205
|
+
/**
|
|
206
|
+
* Sends a ping request to the server to verify connectivity.
|
|
207
|
+
*
|
|
208
|
+
* @param message - Optional message to include in the ping
|
|
209
|
+
* @returns A promise that resolves with the ping response containing the message and timestamp
|
|
210
|
+
* @throws Error if the client is not connected
|
|
211
|
+
*
|
|
212
|
+
* @example
|
|
213
|
+
* ```typescript
|
|
214
|
+
* const response = await client.ping("health check");
|
|
215
|
+
* console.log(`Server responded at ${new Date(response.timestamp)}`);
|
|
216
|
+
* ```
|
|
217
|
+
*/
|
|
218
|
+
ping(message?: string): Promise<{
|
|
219
|
+
message: string;
|
|
220
|
+
timestamp: number;
|
|
221
|
+
protocolVersion?: number;
|
|
222
|
+
}>;
|
|
223
|
+
/**
|
|
224
|
+
* Verify that the server's protocol version matches the SDK's expected version
|
|
225
|
+
*/
|
|
226
|
+
private verifyProtocolVersion;
|
|
227
|
+
/**
|
|
228
|
+
* Gets the ID of the most recently updated session.
|
|
229
|
+
*
|
|
230
|
+
* This is useful for resuming the last conversation when the session ID
|
|
231
|
+
* was not stored.
|
|
232
|
+
*
|
|
233
|
+
* @returns A promise that resolves with the session ID, or undefined if no sessions exist
|
|
234
|
+
* @throws Error if the client is not connected
|
|
235
|
+
*
|
|
236
|
+
* @example
|
|
237
|
+
* ```typescript
|
|
238
|
+
* const lastId = await client.getLastSessionId();
|
|
239
|
+
* if (lastId) {
|
|
240
|
+
* const session = await client.resumeSession(lastId);
|
|
241
|
+
* }
|
|
242
|
+
* ```
|
|
243
|
+
*/
|
|
244
|
+
getLastSessionId(): Promise<string | undefined>;
|
|
245
|
+
/**
|
|
246
|
+
* Deletes a session and its data from disk.
|
|
247
|
+
*
|
|
248
|
+
* This permanently removes the session and all its conversation history.
|
|
249
|
+
* The session cannot be resumed after deletion.
|
|
250
|
+
*
|
|
251
|
+
* @param sessionId - The ID of the session to delete
|
|
252
|
+
* @returns A promise that resolves when the session is deleted
|
|
253
|
+
* @throws Error if the session does not exist or deletion fails
|
|
254
|
+
*
|
|
255
|
+
* @example
|
|
256
|
+
* ```typescript
|
|
257
|
+
* await client.deleteSession("session-123");
|
|
258
|
+
* ```
|
|
259
|
+
*/
|
|
260
|
+
deleteSession(sessionId: string): Promise<void>;
|
|
261
|
+
/**
|
|
262
|
+
* Lists all available sessions known to the server.
|
|
263
|
+
*
|
|
264
|
+
* Returns metadata about each session including ID, timestamps, and summary.
|
|
265
|
+
*
|
|
266
|
+
* @returns A promise that resolves with an array of session metadata
|
|
267
|
+
* @throws Error if the client is not connected
|
|
268
|
+
*
|
|
269
|
+
* @example
|
|
270
|
+
* ```typescript
|
|
271
|
+
* const sessions = await client.listSessions();
|
|
272
|
+
* for (const session of sessions) {
|
|
273
|
+
* console.log(`${session.sessionId}: ${session.summary}`);
|
|
274
|
+
* }
|
|
275
|
+
* ```
|
|
276
|
+
*/
|
|
277
|
+
listSessions(): Promise<SessionMetadata[]>;
|
|
278
|
+
/**
|
|
279
|
+
* Start the CLI server process
|
|
280
|
+
*/
|
|
281
|
+
private startCLIServer;
|
|
282
|
+
/**
|
|
283
|
+
* Connect to the CLI server (via socket or stdio)
|
|
284
|
+
*/
|
|
285
|
+
private connectToServer;
|
|
286
|
+
/**
|
|
287
|
+
* Connect via stdio pipes
|
|
288
|
+
*/
|
|
289
|
+
private connectViaStdio;
|
|
290
|
+
/**
|
|
291
|
+
* Connect to the CLI server via TCP socket
|
|
292
|
+
*/
|
|
293
|
+
private connectViaTcp;
|
|
294
|
+
private attachConnectionHandlers;
|
|
295
|
+
private handleSessionEventNotification;
|
|
296
|
+
private handleToolCallRequest;
|
|
297
|
+
private executeToolCall;
|
|
298
|
+
private handlePermissionRequest;
|
|
299
|
+
private normalizeToolResult;
|
|
300
|
+
private isToolResultObject;
|
|
301
|
+
private buildUnsupportedToolResult;
|
|
302
|
+
/**
|
|
303
|
+
* Attempt to reconnect to the server
|
|
304
|
+
*/
|
|
305
|
+
private reconnect;
|
|
306
|
+
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Generated from: @github/copilot/session-events.schema.json
|
|
5
5
|
* Generated by: scripts/generate-session-types.ts
|
|
6
|
-
* Generated at: 2026-01-
|
|
6
|
+
* Generated at: 2026-01-13T00:08:20.716Z
|
|
7
7
|
*
|
|
8
8
|
* To update these types:
|
|
9
9
|
* 1. Update the schema in copilot-agent-runtime
|
|
@@ -121,6 +121,13 @@ export type SessionEvent = {
|
|
|
121
121
|
}[];
|
|
122
122
|
source?: string;
|
|
123
123
|
};
|
|
124
|
+
} | {
|
|
125
|
+
id: string;
|
|
126
|
+
timestamp: string;
|
|
127
|
+
parentId: string | null;
|
|
128
|
+
ephemeral: true;
|
|
129
|
+
type: "pending_messages.modified";
|
|
130
|
+
data: {};
|
|
124
131
|
} | {
|
|
125
132
|
id: string;
|
|
126
133
|
timestamp: string;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copilot SDK - TypeScript/Node.js Client
|
|
3
|
+
*
|
|
4
|
+
* JSON-RPC based SDK for programmatic control of GitHub Copilot CLI
|
|
5
|
+
*/
|
|
6
|
+
export { CopilotClient } from "./client.js";
|
|
7
|
+
export { CopilotSession } from "./session.js";
|
|
8
|
+
export { defineTool } from "./types.js";
|
|
9
|
+
export type { ConnectionState, CopilotClientOptions, CustomAgentConfig, MCPLocalServerConfig, MCPRemoteServerConfig, MCPServerConfig, MessageOptions, PermissionHandler, PermissionRequest, PermissionRequestResult, ResumeSessionConfig, SessionConfig, SessionEvent, SessionEventHandler, SessionMetadata, SystemMessageAppendConfig, SystemMessageConfig, SystemMessageReplaceConfig, Tool, ToolHandler, ToolInvocation, ToolResultObject, ZodSchema, } from "./types.js";
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copilot Session - represents a single conversation session with the Copilot CLI.
|
|
3
|
+
* @module session
|
|
4
|
+
*/
|
|
5
|
+
import type { MessageConnection } from "vscode-jsonrpc/node";
|
|
6
|
+
import type { MessageOptions, PermissionHandler, PermissionRequestResult, SessionEvent, SessionEventHandler, Tool, ToolHandler } from "./types.js";
|
|
7
|
+
/**
|
|
8
|
+
* Represents a single conversation session with the Copilot CLI.
|
|
9
|
+
*
|
|
10
|
+
* A session maintains conversation state, handles events, and manages tool execution.
|
|
11
|
+
* Sessions are created via {@link CopilotClient.createSession} or resumed via
|
|
12
|
+
* {@link CopilotClient.resumeSession}.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* const session = await client.createSession({ model: "gpt-4" });
|
|
17
|
+
*
|
|
18
|
+
* // Subscribe to events
|
|
19
|
+
* const unsubscribe = session.on((event) => {
|
|
20
|
+
* if (event.type === "assistant.message") {
|
|
21
|
+
* console.log(event.data.content);
|
|
22
|
+
* }
|
|
23
|
+
* });
|
|
24
|
+
*
|
|
25
|
+
* // Send a message
|
|
26
|
+
* await session.send({ prompt: "Hello, world!" });
|
|
27
|
+
*
|
|
28
|
+
* // Clean up
|
|
29
|
+
* unsubscribe();
|
|
30
|
+
* await session.destroy();
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export declare class CopilotSession {
|
|
34
|
+
readonly sessionId: string;
|
|
35
|
+
private connection;
|
|
36
|
+
private eventHandlers;
|
|
37
|
+
private toolHandlers;
|
|
38
|
+
private permissionHandler?;
|
|
39
|
+
/**
|
|
40
|
+
* Creates a new CopilotSession instance.
|
|
41
|
+
*
|
|
42
|
+
* @param sessionId - The unique identifier for this session
|
|
43
|
+
* @param connection - The JSON-RPC message connection to the Copilot CLI
|
|
44
|
+
* @internal This constructor is internal. Use {@link CopilotClient.createSession} to create sessions.
|
|
45
|
+
*/
|
|
46
|
+
constructor(sessionId: string, connection: MessageConnection);
|
|
47
|
+
/**
|
|
48
|
+
* Sends a message to this session and waits for the response.
|
|
49
|
+
*
|
|
50
|
+
* The message is processed asynchronously. Subscribe to events via {@link on}
|
|
51
|
+
* to receive streaming responses and other session events.
|
|
52
|
+
*
|
|
53
|
+
* @param options - The message options including the prompt and optional attachments
|
|
54
|
+
* @returns A promise that resolves with the message ID of the response
|
|
55
|
+
* @throws Error if the session has been destroyed or the connection fails
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* ```typescript
|
|
59
|
+
* const messageId = await session.send({
|
|
60
|
+
* prompt: "Explain this code",
|
|
61
|
+
* attachments: [{ type: "file", path: "./src/index.ts" }]
|
|
62
|
+
* });
|
|
63
|
+
* ```
|
|
64
|
+
*/
|
|
65
|
+
send(options: MessageOptions): Promise<string>;
|
|
66
|
+
/**
|
|
67
|
+
* Subscribes to events from this session.
|
|
68
|
+
*
|
|
69
|
+
* Events include assistant messages, tool executions, errors, and session state changes.
|
|
70
|
+
* Multiple handlers can be registered and will all receive events.
|
|
71
|
+
*
|
|
72
|
+
* @param handler - A callback function that receives session events
|
|
73
|
+
* @returns A function that, when called, unsubscribes the handler
|
|
74
|
+
*
|
|
75
|
+
* @example
|
|
76
|
+
* ```typescript
|
|
77
|
+
* const unsubscribe = session.on((event) => {
|
|
78
|
+
* switch (event.type) {
|
|
79
|
+
* case "assistant.message":
|
|
80
|
+
* console.log("Assistant:", event.data.content);
|
|
81
|
+
* break;
|
|
82
|
+
* case "session.error":
|
|
83
|
+
* console.error("Error:", event.data.message);
|
|
84
|
+
* break;
|
|
85
|
+
* }
|
|
86
|
+
* });
|
|
87
|
+
*
|
|
88
|
+
* // Later, to stop receiving events:
|
|
89
|
+
* unsubscribe();
|
|
90
|
+
* ```
|
|
91
|
+
*/
|
|
92
|
+
on(handler: SessionEventHandler): () => void;
|
|
93
|
+
/**
|
|
94
|
+
* Dispatches an event to all registered handlers.
|
|
95
|
+
*
|
|
96
|
+
* @param event - The session event to dispatch
|
|
97
|
+
* @internal This method is for internal use by the SDK.
|
|
98
|
+
*/
|
|
99
|
+
_dispatchEvent(event: SessionEvent): void;
|
|
100
|
+
/**
|
|
101
|
+
* Registers custom tool handlers for this session.
|
|
102
|
+
*
|
|
103
|
+
* Tools allow the assistant to execute custom functions. When the assistant
|
|
104
|
+
* invokes a tool, the corresponding handler is called with the tool arguments.
|
|
105
|
+
*
|
|
106
|
+
* @param tools - An array of tool definitions with their handlers, or undefined to clear all tools
|
|
107
|
+
* @internal This method is typically called internally when creating a session with tools.
|
|
108
|
+
*/
|
|
109
|
+
registerTools(tools?: Tool[]): void;
|
|
110
|
+
/**
|
|
111
|
+
* Retrieves a registered tool handler by name.
|
|
112
|
+
*
|
|
113
|
+
* @param name - The name of the tool to retrieve
|
|
114
|
+
* @returns The tool handler if found, or undefined
|
|
115
|
+
* @internal This method is for internal use by the SDK.
|
|
116
|
+
*/
|
|
117
|
+
getToolHandler(name: string): ToolHandler | undefined;
|
|
118
|
+
/**
|
|
119
|
+
* Registers a handler for permission requests.
|
|
120
|
+
*
|
|
121
|
+
* When the assistant needs permission to perform certain actions (e.g., file operations),
|
|
122
|
+
* this handler is called to approve or deny the request.
|
|
123
|
+
*
|
|
124
|
+
* @param handler - The permission handler function, or undefined to remove the handler
|
|
125
|
+
* @internal This method is typically called internally when creating a session.
|
|
126
|
+
*/
|
|
127
|
+
registerPermissionHandler(handler?: PermissionHandler): void;
|
|
128
|
+
/**
|
|
129
|
+
* Handles a permission request from the Copilot CLI.
|
|
130
|
+
*
|
|
131
|
+
* @param request - The permission request data from the CLI
|
|
132
|
+
* @returns A promise that resolves with the permission decision
|
|
133
|
+
* @internal This method is for internal use by the SDK.
|
|
134
|
+
*/
|
|
135
|
+
_handlePermissionRequest(request: unknown): Promise<PermissionRequestResult>;
|
|
136
|
+
/**
|
|
137
|
+
* Retrieves all events and messages from this session's history.
|
|
138
|
+
*
|
|
139
|
+
* This returns the complete conversation history including user messages,
|
|
140
|
+
* assistant responses, tool executions, and other session events.
|
|
141
|
+
*
|
|
142
|
+
* @returns A promise that resolves with an array of all session events
|
|
143
|
+
* @throws Error if the session has been destroyed or the connection fails
|
|
144
|
+
*
|
|
145
|
+
* @example
|
|
146
|
+
* ```typescript
|
|
147
|
+
* const events = await session.getMessages();
|
|
148
|
+
* for (const event of events) {
|
|
149
|
+
* if (event.type === "assistant.message") {
|
|
150
|
+
* console.log("Assistant:", event.data.content);
|
|
151
|
+
* }
|
|
152
|
+
* }
|
|
153
|
+
* ```
|
|
154
|
+
*/
|
|
155
|
+
getMessages(): Promise<SessionEvent[]>;
|
|
156
|
+
/**
|
|
157
|
+
* Destroys this session and releases all associated resources.
|
|
158
|
+
*
|
|
159
|
+
* After calling this method, the session can no longer be used. All event
|
|
160
|
+
* handlers and tool handlers are cleared. To continue the conversation,
|
|
161
|
+
* use {@link CopilotClient.resumeSession} with the session ID.
|
|
162
|
+
*
|
|
163
|
+
* @returns A promise that resolves when the session is destroyed
|
|
164
|
+
* @throws Error if the connection fails
|
|
165
|
+
*
|
|
166
|
+
* @example
|
|
167
|
+
* ```typescript
|
|
168
|
+
* // Clean up when done
|
|
169
|
+
* await session.destroy();
|
|
170
|
+
* ```
|
|
171
|
+
*/
|
|
172
|
+
destroy(): Promise<void>;
|
|
173
|
+
/**
|
|
174
|
+
* Aborts the currently processing message in this session.
|
|
175
|
+
*
|
|
176
|
+
* Use this to cancel a long-running request. The session remains valid
|
|
177
|
+
* and can continue to be used for new messages.
|
|
178
|
+
*
|
|
179
|
+
* @returns A promise that resolves when the abort request is acknowledged
|
|
180
|
+
* @throws Error if the session has been destroyed or the connection fails
|
|
181
|
+
*
|
|
182
|
+
* @example
|
|
183
|
+
* ```typescript
|
|
184
|
+
* // Start a long-running request
|
|
185
|
+
* const messagePromise = session.send({ prompt: "Write a very long story..." });
|
|
186
|
+
*
|
|
187
|
+
* // Abort after 5 seconds
|
|
188
|
+
* setTimeout(async () => {
|
|
189
|
+
* await session.abort();
|
|
190
|
+
* }, 5000);
|
|
191
|
+
* ```
|
|
192
|
+
*/
|
|
193
|
+
abort(): Promise<void>;
|
|
194
|
+
}
|
|
@@ -166,6 +166,90 @@ export interface PermissionRequestResult {
|
|
|
166
166
|
export type PermissionHandler = (request: PermissionRequest, invocation: {
|
|
167
167
|
sessionId: string;
|
|
168
168
|
}) => Promise<PermissionRequestResult> | PermissionRequestResult;
|
|
169
|
+
/**
|
|
170
|
+
* Base interface for MCP server configuration.
|
|
171
|
+
*/
|
|
172
|
+
interface MCPServerConfigBase {
|
|
173
|
+
/**
|
|
174
|
+
* List of tools to include from this server. [] means none. "*" means all.
|
|
175
|
+
*/
|
|
176
|
+
tools: string[];
|
|
177
|
+
/**
|
|
178
|
+
* Indicates "remote" or "local" server type.
|
|
179
|
+
* If not specified, defaults to "local".
|
|
180
|
+
*/
|
|
181
|
+
type?: string;
|
|
182
|
+
/**
|
|
183
|
+
* Optional timeout in milliseconds for tool calls to this server.
|
|
184
|
+
*/
|
|
185
|
+
timeout?: number;
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Configuration for a local/stdio MCP server.
|
|
189
|
+
*/
|
|
190
|
+
export interface MCPLocalServerConfig extends MCPServerConfigBase {
|
|
191
|
+
type?: "local" | "stdio";
|
|
192
|
+
command: string;
|
|
193
|
+
args: string[];
|
|
194
|
+
/**
|
|
195
|
+
* Environment variables to pass to the server.
|
|
196
|
+
*/
|
|
197
|
+
env?: Record<string, string>;
|
|
198
|
+
cwd?: string;
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Configuration for a remote MCP server (HTTP or SSE).
|
|
202
|
+
*/
|
|
203
|
+
export interface MCPRemoteServerConfig extends MCPServerConfigBase {
|
|
204
|
+
type: "http" | "sse";
|
|
205
|
+
/**
|
|
206
|
+
* URL of the remote server.
|
|
207
|
+
*/
|
|
208
|
+
url: string;
|
|
209
|
+
/**
|
|
210
|
+
* Optional HTTP headers to include in requests.
|
|
211
|
+
*/
|
|
212
|
+
headers?: Record<string, string>;
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Union type for MCP server configurations.
|
|
216
|
+
*/
|
|
217
|
+
export type MCPServerConfig = MCPLocalServerConfig | MCPRemoteServerConfig;
|
|
218
|
+
/**
|
|
219
|
+
* Configuration for a custom agent.
|
|
220
|
+
*/
|
|
221
|
+
export interface CustomAgentConfig {
|
|
222
|
+
/**
|
|
223
|
+
* Unique name of the custom agent.
|
|
224
|
+
*/
|
|
225
|
+
name: string;
|
|
226
|
+
/**
|
|
227
|
+
* Display name for UI purposes.
|
|
228
|
+
*/
|
|
229
|
+
displayName?: string;
|
|
230
|
+
/**
|
|
231
|
+
* Description of what the agent does.
|
|
232
|
+
*/
|
|
233
|
+
description?: string;
|
|
234
|
+
/**
|
|
235
|
+
* List of tool names the agent can use.
|
|
236
|
+
* Use null or undefined for all tools.
|
|
237
|
+
*/
|
|
238
|
+
tools?: string[] | null;
|
|
239
|
+
/**
|
|
240
|
+
* The prompt content for the agent.
|
|
241
|
+
*/
|
|
242
|
+
prompt: string;
|
|
243
|
+
/**
|
|
244
|
+
* MCP servers specific to this agent.
|
|
245
|
+
*/
|
|
246
|
+
mcpServers?: Record<string, MCPServerConfig>;
|
|
247
|
+
/**
|
|
248
|
+
* Whether the agent should be available for model inference.
|
|
249
|
+
* @default true
|
|
250
|
+
*/
|
|
251
|
+
infer?: boolean;
|
|
252
|
+
}
|
|
169
253
|
export interface SessionConfig {
|
|
170
254
|
/**
|
|
171
255
|
* Optional custom session ID
|
|
@@ -206,11 +290,20 @@ export interface SessionConfig {
|
|
|
206
290
|
*/
|
|
207
291
|
onPermissionRequest?: PermissionHandler;
|
|
208
292
|
streaming?: boolean;
|
|
293
|
+
/**
|
|
294
|
+
* MCP server configurations for the session.
|
|
295
|
+
* Keys are server names, values are server configurations.
|
|
296
|
+
*/
|
|
297
|
+
mcpServers?: Record<string, MCPServerConfig>;
|
|
298
|
+
/**
|
|
299
|
+
* Custom agent configurations for the session.
|
|
300
|
+
*/
|
|
301
|
+
customAgents?: CustomAgentConfig[];
|
|
209
302
|
}
|
|
210
303
|
/**
|
|
211
304
|
* Configuration for resuming a session
|
|
212
305
|
*/
|
|
213
|
-
export type ResumeSessionConfig = Pick<SessionConfig, "tools" | "provider" | "streaming" | "onPermissionRequest">;
|
|
306
|
+
export type ResumeSessionConfig = Pick<SessionConfig, "tools" | "provider" | "streaming" | "onPermissionRequest" | "mcpServers" | "customAgents">;
|
|
214
307
|
/**
|
|
215
308
|
* Configuration for a custom API provider.
|
|
216
309
|
*/
|
|
@@ -288,3 +381,4 @@ export interface SessionMetadata {
|
|
|
288
381
|
summary?: string;
|
|
289
382
|
isRemote: boolean;
|
|
290
383
|
}
|
|
384
|
+
export {};
|
package/dist/session.js
CHANGED
|
@@ -1,4 +1,11 @@
|
|
|
1
1
|
class CopilotSession {
|
|
2
|
+
/**
|
|
3
|
+
* Creates a new CopilotSession instance.
|
|
4
|
+
*
|
|
5
|
+
* @param sessionId - The unique identifier for this session
|
|
6
|
+
* @param connection - The JSON-RPC message connection to the Copilot CLI
|
|
7
|
+
* @internal This constructor is internal. Use {@link CopilotClient.createSession} to create sessions.
|
|
8
|
+
*/
|
|
2
9
|
constructor(sessionId, connection) {
|
|
3
10
|
this.sessionId = sessionId;
|
|
4
11
|
this.connection = connection;
|
|
@@ -7,7 +14,22 @@ class CopilotSession {
|
|
|
7
14
|
toolHandlers = /* @__PURE__ */ new Map();
|
|
8
15
|
permissionHandler;
|
|
9
16
|
/**
|
|
10
|
-
*
|
|
17
|
+
* Sends a message to this session and waits for the response.
|
|
18
|
+
*
|
|
19
|
+
* The message is processed asynchronously. Subscribe to events via {@link on}
|
|
20
|
+
* to receive streaming responses and other session events.
|
|
21
|
+
*
|
|
22
|
+
* @param options - The message options including the prompt and optional attachments
|
|
23
|
+
* @returns A promise that resolves with the message ID of the response
|
|
24
|
+
* @throws Error if the session has been destroyed or the connection fails
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```typescript
|
|
28
|
+
* const messageId = await session.send({
|
|
29
|
+
* prompt: "Explain this code",
|
|
30
|
+
* attachments: [{ type: "file", path: "./src/index.ts" }]
|
|
31
|
+
* });
|
|
32
|
+
* ```
|
|
11
33
|
*/
|
|
12
34
|
async send(options) {
|
|
13
35
|
const response = await this.connection.sendRequest("session.send", {
|
|
@@ -19,8 +41,30 @@ class CopilotSession {
|
|
|
19
41
|
return response.messageId;
|
|
20
42
|
}
|
|
21
43
|
/**
|
|
22
|
-
*
|
|
23
|
-
*
|
|
44
|
+
* Subscribes to events from this session.
|
|
45
|
+
*
|
|
46
|
+
* Events include assistant messages, tool executions, errors, and session state changes.
|
|
47
|
+
* Multiple handlers can be registered and will all receive events.
|
|
48
|
+
*
|
|
49
|
+
* @param handler - A callback function that receives session events
|
|
50
|
+
* @returns A function that, when called, unsubscribes the handler
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* ```typescript
|
|
54
|
+
* const unsubscribe = session.on((event) => {
|
|
55
|
+
* switch (event.type) {
|
|
56
|
+
* case "assistant.message":
|
|
57
|
+
* console.log("Assistant:", event.data.content);
|
|
58
|
+
* break;
|
|
59
|
+
* case "session.error":
|
|
60
|
+
* console.error("Error:", event.data.message);
|
|
61
|
+
* break;
|
|
62
|
+
* }
|
|
63
|
+
* });
|
|
64
|
+
*
|
|
65
|
+
* // Later, to stop receiving events:
|
|
66
|
+
* unsubscribe();
|
|
67
|
+
* ```
|
|
24
68
|
*/
|
|
25
69
|
on(handler) {
|
|
26
70
|
this.eventHandlers.add(handler);
|
|
@@ -29,7 +73,10 @@ class CopilotSession {
|
|
|
29
73
|
};
|
|
30
74
|
}
|
|
31
75
|
/**
|
|
32
|
-
*
|
|
76
|
+
* Dispatches an event to all registered handlers.
|
|
77
|
+
*
|
|
78
|
+
* @param event - The session event to dispatch
|
|
79
|
+
* @internal This method is for internal use by the SDK.
|
|
33
80
|
*/
|
|
34
81
|
_dispatchEvent(event) {
|
|
35
82
|
for (const handler of this.eventHandlers) {
|
|
@@ -39,6 +86,15 @@ class CopilotSession {
|
|
|
39
86
|
}
|
|
40
87
|
}
|
|
41
88
|
}
|
|
89
|
+
/**
|
|
90
|
+
* Registers custom tool handlers for this session.
|
|
91
|
+
*
|
|
92
|
+
* Tools allow the assistant to execute custom functions. When the assistant
|
|
93
|
+
* invokes a tool, the corresponding handler is called with the tool arguments.
|
|
94
|
+
*
|
|
95
|
+
* @param tools - An array of tool definitions with their handlers, or undefined to clear all tools
|
|
96
|
+
* @internal This method is typically called internally when creating a session with tools.
|
|
97
|
+
*/
|
|
42
98
|
registerTools(tools) {
|
|
43
99
|
this.toolHandlers.clear();
|
|
44
100
|
if (!tools) {
|
|
@@ -48,12 +104,35 @@ class CopilotSession {
|
|
|
48
104
|
this.toolHandlers.set(tool.name, tool.handler);
|
|
49
105
|
}
|
|
50
106
|
}
|
|
107
|
+
/**
|
|
108
|
+
* Retrieves a registered tool handler by name.
|
|
109
|
+
*
|
|
110
|
+
* @param name - The name of the tool to retrieve
|
|
111
|
+
* @returns The tool handler if found, or undefined
|
|
112
|
+
* @internal This method is for internal use by the SDK.
|
|
113
|
+
*/
|
|
51
114
|
getToolHandler(name) {
|
|
52
115
|
return this.toolHandlers.get(name);
|
|
53
116
|
}
|
|
117
|
+
/**
|
|
118
|
+
* Registers a handler for permission requests.
|
|
119
|
+
*
|
|
120
|
+
* When the assistant needs permission to perform certain actions (e.g., file operations),
|
|
121
|
+
* this handler is called to approve or deny the request.
|
|
122
|
+
*
|
|
123
|
+
* @param handler - The permission handler function, or undefined to remove the handler
|
|
124
|
+
* @internal This method is typically called internally when creating a session.
|
|
125
|
+
*/
|
|
54
126
|
registerPermissionHandler(handler) {
|
|
55
127
|
this.permissionHandler = handler;
|
|
56
128
|
}
|
|
129
|
+
/**
|
|
130
|
+
* Handles a permission request from the Copilot CLI.
|
|
131
|
+
*
|
|
132
|
+
* @param request - The permission request data from the CLI
|
|
133
|
+
* @returns A promise that resolves with the permission decision
|
|
134
|
+
* @internal This method is for internal use by the SDK.
|
|
135
|
+
*/
|
|
57
136
|
async _handlePermissionRequest(request) {
|
|
58
137
|
if (!this.permissionHandler) {
|
|
59
138
|
return { kind: "denied-no-approval-rule-and-could-not-request-from-user" };
|
|
@@ -68,7 +147,23 @@ class CopilotSession {
|
|
|
68
147
|
}
|
|
69
148
|
}
|
|
70
149
|
/**
|
|
71
|
-
*
|
|
150
|
+
* Retrieves all events and messages from this session's history.
|
|
151
|
+
*
|
|
152
|
+
* This returns the complete conversation history including user messages,
|
|
153
|
+
* assistant responses, tool executions, and other session events.
|
|
154
|
+
*
|
|
155
|
+
* @returns A promise that resolves with an array of all session events
|
|
156
|
+
* @throws Error if the session has been destroyed or the connection fails
|
|
157
|
+
*
|
|
158
|
+
* @example
|
|
159
|
+
* ```typescript
|
|
160
|
+
* const events = await session.getMessages();
|
|
161
|
+
* for (const event of events) {
|
|
162
|
+
* if (event.type === "assistant.message") {
|
|
163
|
+
* console.log("Assistant:", event.data.content);
|
|
164
|
+
* }
|
|
165
|
+
* }
|
|
166
|
+
* ```
|
|
72
167
|
*/
|
|
73
168
|
async getMessages() {
|
|
74
169
|
const response = await this.connection.sendRequest("session.getMessages", {
|
|
@@ -77,7 +172,20 @@ class CopilotSession {
|
|
|
77
172
|
return response.events;
|
|
78
173
|
}
|
|
79
174
|
/**
|
|
80
|
-
*
|
|
175
|
+
* Destroys this session and releases all associated resources.
|
|
176
|
+
*
|
|
177
|
+
* After calling this method, the session can no longer be used. All event
|
|
178
|
+
* handlers and tool handlers are cleared. To continue the conversation,
|
|
179
|
+
* use {@link CopilotClient.resumeSession} with the session ID.
|
|
180
|
+
*
|
|
181
|
+
* @returns A promise that resolves when the session is destroyed
|
|
182
|
+
* @throws Error if the connection fails
|
|
183
|
+
*
|
|
184
|
+
* @example
|
|
185
|
+
* ```typescript
|
|
186
|
+
* // Clean up when done
|
|
187
|
+
* await session.destroy();
|
|
188
|
+
* ```
|
|
81
189
|
*/
|
|
82
190
|
async destroy() {
|
|
83
191
|
await this.connection.sendRequest("session.destroy", {
|
|
@@ -88,7 +196,24 @@ class CopilotSession {
|
|
|
88
196
|
this.permissionHandler = void 0;
|
|
89
197
|
}
|
|
90
198
|
/**
|
|
91
|
-
*
|
|
199
|
+
* Aborts the currently processing message in this session.
|
|
200
|
+
*
|
|
201
|
+
* Use this to cancel a long-running request. The session remains valid
|
|
202
|
+
* and can continue to be used for new messages.
|
|
203
|
+
*
|
|
204
|
+
* @returns A promise that resolves when the abort request is acknowledged
|
|
205
|
+
* @throws Error if the session has been destroyed or the connection fails
|
|
206
|
+
*
|
|
207
|
+
* @example
|
|
208
|
+
* ```typescript
|
|
209
|
+
* // Start a long-running request
|
|
210
|
+
* const messagePromise = session.send({ prompt: "Write a very long story..." });
|
|
211
|
+
*
|
|
212
|
+
* // Abort after 5 seconds
|
|
213
|
+
* setTimeout(async () => {
|
|
214
|
+
* await session.abort();
|
|
215
|
+
* }, 5000);
|
|
216
|
+
* ```
|
|
92
217
|
*/
|
|
93
218
|
async abort() {
|
|
94
219
|
await this.connection.sendRequest("session.abort", {
|
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.11",
|
|
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",
|
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
"lint:fix": "eslint --fix \"src/**/*.ts\" \"test/**/*.ts\"",
|
|
27
27
|
"typecheck": "tsc --noEmit",
|
|
28
28
|
"generate:session-types": "tsx scripts/generate-session-types.ts",
|
|
29
|
+
"update:protocol-version": "tsx scripts/generate-protocol-version.ts",
|
|
29
30
|
"prepublishOnly": "npm run build",
|
|
30
31
|
"package": "npm run clean && npm run build && node scripts/set-version.js && npm pack && npm version 0.1.0 --no-git-tag-version --allow-same-version"
|
|
31
32
|
},
|
|
@@ -39,12 +40,12 @@
|
|
|
39
40
|
"author": "GitHub",
|
|
40
41
|
"license": "MIT",
|
|
41
42
|
"dependencies": {
|
|
42
|
-
"@github/copilot": "^0.0.
|
|
43
|
+
"@github/copilot": "^0.0.382-0",
|
|
43
44
|
"vscode-jsonrpc": "^8.2.1",
|
|
44
45
|
"zod": "^4.3.5"
|
|
45
46
|
},
|
|
46
47
|
"devDependencies": {
|
|
47
|
-
"@types/node": "^22.
|
|
48
|
+
"@types/node": "^22.19.6",
|
|
48
49
|
"@typescript-eslint/eslint-plugin": "^8.0.0",
|
|
49
50
|
"@typescript-eslint/parser": "^8.0.0",
|
|
50
51
|
"esbuild": "^0.27.0",
|
package/dist/client.d.ts
DELETED
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
import { CopilotSession } from "./session.js";
|
|
2
|
-
import type { ConnectionState, CopilotClientOptions, ResumeSessionConfig, SessionConfig, SessionMetadata } from "./types.js";
|
|
3
|
-
export declare class CopilotClient {
|
|
4
|
-
private cliProcess;
|
|
5
|
-
private connection;
|
|
6
|
-
private socket;
|
|
7
|
-
private actualPort;
|
|
8
|
-
private actualHost;
|
|
9
|
-
private state;
|
|
10
|
-
private sessions;
|
|
11
|
-
private options;
|
|
12
|
-
private isExternalServer;
|
|
13
|
-
private forceStopping;
|
|
14
|
-
constructor(options?: CopilotClientOptions);
|
|
15
|
-
/**
|
|
16
|
-
* Parse CLI URL into host and port
|
|
17
|
-
* Supports formats: "host:port", "http://host:port", "https://host:port", or just "port"
|
|
18
|
-
*/
|
|
19
|
-
private parseCliUrl;
|
|
20
|
-
/**
|
|
21
|
-
* Start the CLI server and establish connection
|
|
22
|
-
*/
|
|
23
|
-
start(): Promise<void>;
|
|
24
|
-
/**
|
|
25
|
-
* Stop the CLI server and close all sessions
|
|
26
|
-
* Returns array of errors encountered during cleanup (empty if all succeeded)
|
|
27
|
-
*/
|
|
28
|
-
stop(): Promise<Error[]>;
|
|
29
|
-
/**
|
|
30
|
-
* Force stop the CLI server without graceful cleanup
|
|
31
|
-
* Use when normal stop() fails or takes too long
|
|
32
|
-
*/
|
|
33
|
-
forceStop(): Promise<void>;
|
|
34
|
-
/**
|
|
35
|
-
* Create a new session
|
|
36
|
-
*/
|
|
37
|
-
createSession(config?: SessionConfig): Promise<CopilotSession>;
|
|
38
|
-
/**
|
|
39
|
-
* Resume an existing session
|
|
40
|
-
*/
|
|
41
|
-
resumeSession(sessionId: string, config?: ResumeSessionConfig): Promise<CopilotSession>;
|
|
42
|
-
/**
|
|
43
|
-
* Get connection state
|
|
44
|
-
*/
|
|
45
|
-
getState(): ConnectionState;
|
|
46
|
-
/**
|
|
47
|
-
* Ping the server
|
|
48
|
-
*/
|
|
49
|
-
ping(message?: string): Promise<{
|
|
50
|
-
message: string;
|
|
51
|
-
timestamp: number;
|
|
52
|
-
}>;
|
|
53
|
-
/**
|
|
54
|
-
* Get the ID of the most recently updated session
|
|
55
|
-
* @returns The session ID, or undefined if no sessions exist
|
|
56
|
-
*/
|
|
57
|
-
getLastSessionId(): Promise<string | undefined>;
|
|
58
|
-
/**
|
|
59
|
-
* Delete a session and its data from disk
|
|
60
|
-
* @param sessionId The ID of the session to delete
|
|
61
|
-
*/
|
|
62
|
-
deleteSession(sessionId: string): Promise<void>;
|
|
63
|
-
/**
|
|
64
|
-
* List all available sessions
|
|
65
|
-
* @returns Array of session metadata
|
|
66
|
-
*/
|
|
67
|
-
listSessions(): Promise<SessionMetadata[]>;
|
|
68
|
-
/**
|
|
69
|
-
* Start the CLI server process
|
|
70
|
-
*/
|
|
71
|
-
private startCLIServer;
|
|
72
|
-
/**
|
|
73
|
-
* Connect to the CLI server (via socket or stdio)
|
|
74
|
-
*/
|
|
75
|
-
private connectToServer;
|
|
76
|
-
/**
|
|
77
|
-
* Connect via stdio pipes
|
|
78
|
-
*/
|
|
79
|
-
private connectViaStdio;
|
|
80
|
-
/**
|
|
81
|
-
* Connect to the CLI server via TCP socket
|
|
82
|
-
*/
|
|
83
|
-
private connectViaTcp;
|
|
84
|
-
private attachConnectionHandlers;
|
|
85
|
-
private handleSessionEventNotification;
|
|
86
|
-
private handleToolCallRequest;
|
|
87
|
-
private executeToolCall;
|
|
88
|
-
private handlePermissionRequest;
|
|
89
|
-
private normalizeToolResult;
|
|
90
|
-
private isToolResultObject;
|
|
91
|
-
private buildUnsupportedToolResult;
|
|
92
|
-
/**
|
|
93
|
-
* Attempt to reconnect to the server
|
|
94
|
-
*/
|
|
95
|
-
private reconnect;
|
|
96
|
-
}
|
package/dist/index.d.ts
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Copilot SDK - TypeScript/Node.js Client
|
|
3
|
-
*
|
|
4
|
-
* JSON-RPC based SDK for programmatic control of GitHub Copilot CLI
|
|
5
|
-
*/
|
|
6
|
-
export { CopilotClient } from "./client.js";
|
|
7
|
-
export { CopilotSession } from "./session.js";
|
|
8
|
-
export { defineTool } from "./types.js";
|
|
9
|
-
export type { ConnectionState, CopilotClientOptions, MessageOptions, PermissionHandler, PermissionRequest, PermissionRequestResult, ResumeSessionConfig, SessionConfig, SessionEvent, SessionEventHandler, SessionMetadata, SystemMessageAppendConfig, SystemMessageConfig, SystemMessageReplaceConfig, Tool, ToolHandler, ToolInvocation, ToolResultObject, ZodSchema, } from "./types.js";
|
package/dist/session.d.ts
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Copilot Session - represents a single conversation session with the CLI
|
|
3
|
-
*/
|
|
4
|
-
import type { MessageConnection } from "vscode-jsonrpc/node";
|
|
5
|
-
import type { MessageOptions, PermissionHandler, PermissionRequestResult, SessionEvent, SessionEventHandler, Tool, ToolHandler } from "./types.js";
|
|
6
|
-
export declare class CopilotSession {
|
|
7
|
-
readonly sessionId: string;
|
|
8
|
-
private connection;
|
|
9
|
-
private eventHandlers;
|
|
10
|
-
private toolHandlers;
|
|
11
|
-
private permissionHandler?;
|
|
12
|
-
constructor(sessionId: string, connection: MessageConnection);
|
|
13
|
-
/**
|
|
14
|
-
* Send a message to this session
|
|
15
|
-
*/
|
|
16
|
-
send(options: MessageOptions): Promise<string>;
|
|
17
|
-
/**
|
|
18
|
-
* Subscribe to events from this session
|
|
19
|
-
* @returns Unsubscribe function
|
|
20
|
-
*/
|
|
21
|
-
on(handler: SessionEventHandler): () => void;
|
|
22
|
-
/**
|
|
23
|
-
* Internal: dispatch an event to all handlers
|
|
24
|
-
*/
|
|
25
|
-
_dispatchEvent(event: SessionEvent): void;
|
|
26
|
-
registerTools(tools?: Tool[]): void;
|
|
27
|
-
getToolHandler(name: string): ToolHandler | undefined;
|
|
28
|
-
registerPermissionHandler(handler?: PermissionHandler): void;
|
|
29
|
-
_handlePermissionRequest(request: unknown): Promise<PermissionRequestResult>;
|
|
30
|
-
/**
|
|
31
|
-
* Get all events/messages from this session
|
|
32
|
-
*/
|
|
33
|
-
getMessages(): Promise<SessionEvent[]>;
|
|
34
|
-
/**
|
|
35
|
-
* Destroy this session and free resources
|
|
36
|
-
*/
|
|
37
|
-
destroy(): Promise<void>;
|
|
38
|
-
/**
|
|
39
|
-
* Abort the currently processing message in this session
|
|
40
|
-
*/
|
|
41
|
-
abort(): Promise<void>;
|
|
42
|
-
}
|