@github/copilot-sdk 0.1.31 → 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/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
@@ -224,7 +225,8 @@ export declare class CopilotClient {
224
225
  */
225
226
  listModels(): Promise<ModelInfo[]>;
226
227
  /**
227
- * Verify that the server's protocol version matches the SDK's expected version
228
+ * Verify that the server's protocol version is within the supported range
229
+ * and store the negotiated version.
228
230
  */
229
231
  private verifyProtocolVersion;
230
232
  /**
@@ -383,6 +385,18 @@ export declare class CopilotClient {
383
385
  private handleSessionLifecycleNotification;
384
386
  private handleUserInputRequest;
385
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;
386
400
  /**
387
401
  * Attempt to reconnect to the server
388
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
@@ -582,10 +584,11 @@ class CopilotClient {
582
584
  }
583
585
  }
584
586
  /**
585
- * Verify that the server's protocol version matches the SDK's expected version
587
+ * Verify that the server's protocol version is within the supported range
588
+ * and store the negotiated version.
586
589
  */
587
590
  async verifyProtocolVersion() {
588
- const expectedVersion = getSdkProtocolVersion();
591
+ const maxVersion = getSdkProtocolVersion();
589
592
  let pingResult;
590
593
  if (this.processExitPromise) {
591
594
  pingResult = await Promise.race([this.ping(), this.processExitPromise]);
@@ -595,14 +598,15 @@ class CopilotClient {
595
598
  const serverVersion = pingResult.protocolVersion;
596
599
  if (serverVersion === void 0) {
597
600
  throw new Error(
598
- `SDK protocol version mismatch: SDK expects version ${expectedVersion}, but server does not report a protocol version. Please update your server to ensure compatibility.`
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.`
599
602
  );
600
603
  }
601
- if (serverVersion !== expectedVersion) {
604
+ if (serverVersion < MIN_PROTOCOL_VERSION || serverVersion > maxVersion) {
602
605
  throw new Error(
603
- `SDK protocol version mismatch: SDK expects version ${expectedVersion}, but server reports version ${serverVersion}. Please update your SDK or server to ensure compatibility.`
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.`
604
607
  );
605
608
  }
609
+ this.negotiatedProtocolVersion = serverVersion;
606
610
  }
607
611
  /**
608
612
  * Gets the ID of the most recently updated session.
@@ -975,6 +979,14 @@ stderr: ${stderrOutput}`
975
979
  this.connection.onNotification("session.lifecycle", (notification) => {
976
980
  this.handleSessionLifecycleNotification(notification);
977
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
+ );
978
990
  this.connection.onRequest(
979
991
  "userInput.request",
980
992
  async (params) => await this.handleUserInputRequest(params)
@@ -1047,6 +1059,98 @@ stderr: ${stderrOutput}`
1047
1059
  const output = await session._handleHooksInvoke(params.hookType, params.input);
1048
1060
  return { output };
1049
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
+ }
1050
1154
  /**
1051
1155
  * Attempt to reconnect to the server
1052
1156
  */
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";
@@ -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
  *
package/dist/session.js CHANGED
@@ -319,6 +319,27 @@ class CopilotSession {
319
319
  registerHooks(hooks) {
320
320
  this.hooks = hooks;
321
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
+ }
322
343
  /**
323
344
  * Handles a user input request from the Copilot CLI.
324
345
  *
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.31",
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",