@github/copilot-sdk 0.1.10-preview.0 → 0.1.10
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 +257 -19
- 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} +113 -6
- package/dist/sdkProtocolVersion.js +7 -0
- package/dist/session.js +150 -7
- package/package.json +4 -3
- package/dist/client.d.ts +0 -95
- package/dist/index.d.ts +0 -9
- package/dist/session.d.ts +0 -39
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) {
|
|
@@ -217,16 +316,42 @@ class CopilotClient {
|
|
|
217
316
|
availableTools: config.availableTools,
|
|
218
317
|
excludedTools: config.excludedTools,
|
|
219
318
|
provider: config.provider,
|
|
220
|
-
|
|
319
|
+
requestPermission: !!config.onPermissionRequest,
|
|
320
|
+
streaming: config.streaming,
|
|
321
|
+
mcpServers: config.mcpServers,
|
|
322
|
+
customAgents: config.customAgents
|
|
221
323
|
});
|
|
222
324
|
const sessionId = response.sessionId;
|
|
223
325
|
const session = new CopilotSession(sessionId, this.connection);
|
|
224
326
|
session.registerTools(config.tools);
|
|
327
|
+
if (config.onPermissionRequest) {
|
|
328
|
+
session.registerPermissionHandler(config.onPermissionRequest);
|
|
329
|
+
}
|
|
225
330
|
this.sessions.set(sessionId, session);
|
|
226
331
|
return session;
|
|
227
332
|
}
|
|
228
333
|
/**
|
|
229
|
-
*
|
|
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
|
+
* ```
|
|
230
355
|
*/
|
|
231
356
|
async resumeSession(sessionId, config = {}) {
|
|
232
357
|
if (!this.connection) {
|
|
@@ -244,22 +369,47 @@ class CopilotClient {
|
|
|
244
369
|
parameters: toJsonSchema(tool.parameters)
|
|
245
370
|
})),
|
|
246
371
|
provider: config.provider,
|
|
247
|
-
|
|
372
|
+
requestPermission: !!config.onPermissionRequest,
|
|
373
|
+
streaming: config.streaming,
|
|
374
|
+
mcpServers: config.mcpServers,
|
|
375
|
+
customAgents: config.customAgents
|
|
248
376
|
});
|
|
249
377
|
const resumedSessionId = response.sessionId;
|
|
250
378
|
const session = new CopilotSession(resumedSessionId, this.connection);
|
|
251
379
|
session.registerTools(config.tools);
|
|
380
|
+
if (config.onPermissionRequest) {
|
|
381
|
+
session.registerPermissionHandler(config.onPermissionRequest);
|
|
382
|
+
}
|
|
252
383
|
this.sessions.set(resumedSessionId, session);
|
|
253
384
|
return session;
|
|
254
385
|
}
|
|
255
386
|
/**
|
|
256
|
-
*
|
|
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
|
+
* ```
|
|
257
397
|
*/
|
|
258
398
|
getState() {
|
|
259
399
|
return this.state;
|
|
260
400
|
}
|
|
261
401
|
/**
|
|
262
|
-
*
|
|
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
|
+
* ```
|
|
263
413
|
*/
|
|
264
414
|
async ping(message) {
|
|
265
415
|
if (!this.connection) {
|
|
@@ -269,8 +419,39 @@ class CopilotClient {
|
|
|
269
419
|
return result;
|
|
270
420
|
}
|
|
271
421
|
/**
|
|
272
|
-
*
|
|
273
|
-
|
|
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
|
+
* ```
|
|
274
455
|
*/
|
|
275
456
|
async getLastSessionId() {
|
|
276
457
|
if (!this.connection) {
|
|
@@ -280,8 +461,19 @@ class CopilotClient {
|
|
|
280
461
|
return response.sessionId;
|
|
281
462
|
}
|
|
282
463
|
/**
|
|
283
|
-
*
|
|
284
|
-
*
|
|
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
|
+
* ```
|
|
285
477
|
*/
|
|
286
478
|
async deleteSession(sessionId) {
|
|
287
479
|
if (!this.connection) {
|
|
@@ -297,8 +489,20 @@ class CopilotClient {
|
|
|
297
489
|
this.sessions.delete(sessionId);
|
|
298
490
|
}
|
|
299
491
|
/**
|
|
300
|
-
*
|
|
301
|
-
*
|
|
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
|
+
* ```
|
|
302
506
|
*/
|
|
303
507
|
async listSessions() {
|
|
304
508
|
if (!this.connection) {
|
|
@@ -333,8 +537,19 @@ class CopilotClient {
|
|
|
333
537
|
const envWithoutNodeDebug = { ...this.options.env };
|
|
334
538
|
delete envWithoutNodeDebug.NODE_DEBUG;
|
|
335
539
|
const isJsFile = this.options.cliPath.endsWith(".js");
|
|
336
|
-
const
|
|
337
|
-
|
|
540
|
+
const isAbsolutePath = this.options.cliPath.startsWith("/") || /^[a-zA-Z]:/.test(this.options.cliPath);
|
|
541
|
+
let command;
|
|
542
|
+
let spawnArgs;
|
|
543
|
+
if (isJsFile) {
|
|
544
|
+
command = "node";
|
|
545
|
+
spawnArgs = [this.options.cliPath, ...args];
|
|
546
|
+
} else if (process.platform === "win32" && !isAbsolutePath) {
|
|
547
|
+
command = "cmd";
|
|
548
|
+
spawnArgs = ["/c", `"${this.options.cliPath}"`, ...args];
|
|
549
|
+
} else {
|
|
550
|
+
command = this.options.cliPath;
|
|
551
|
+
spawnArgs = args;
|
|
552
|
+
}
|
|
338
553
|
this.cliProcess = spawn(command, spawnArgs, {
|
|
339
554
|
stdio: this.options.useStdio ? ["pipe", "pipe", "pipe"] : ["ignore", "pipe", "pipe"],
|
|
340
555
|
cwd: this.options.cwd,
|
|
@@ -450,6 +665,10 @@ class CopilotClient {
|
|
|
450
665
|
"tool.call",
|
|
451
666
|
async (params) => await this.handleToolCallRequest(params)
|
|
452
667
|
);
|
|
668
|
+
this.connection.onRequest(
|
|
669
|
+
"permission.request",
|
|
670
|
+
async (params) => await this.handlePermissionRequest(params)
|
|
671
|
+
);
|
|
453
672
|
this.connection.onClose(() => {
|
|
454
673
|
if (this.state === "connected" && this.options.autoRestart) {
|
|
455
674
|
void this.reconnect();
|
|
@@ -504,6 +723,25 @@ class CopilotClient {
|
|
|
504
723
|
};
|
|
505
724
|
}
|
|
506
725
|
}
|
|
726
|
+
async handlePermissionRequest(params) {
|
|
727
|
+
if (!params || typeof params.sessionId !== "string" || !params.permissionRequest) {
|
|
728
|
+
throw new Error("Invalid permission request payload");
|
|
729
|
+
}
|
|
730
|
+
const session = this.sessions.get(params.sessionId);
|
|
731
|
+
if (!session) {
|
|
732
|
+
throw new Error(`Session not found: ${params.sessionId}`);
|
|
733
|
+
}
|
|
734
|
+
try {
|
|
735
|
+
const result = await session._handlePermissionRequest(params.permissionRequest);
|
|
736
|
+
return { result };
|
|
737
|
+
} catch (_error) {
|
|
738
|
+
return {
|
|
739
|
+
result: {
|
|
740
|
+
kind: "denied-no-approval-rule-and-could-not-request-from-user"
|
|
741
|
+
}
|
|
742
|
+
};
|
|
743
|
+
}
|
|
744
|
+
}
|
|
507
745
|
normalizeToolResult(result) {
|
|
508
746
|
if (result === void 0 || result === null) {
|
|
509
747
|
return {
|
|
@@ -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
|
+
}
|