@github/copilot-sdk
Advanced tools
+15
-1
@@ -22,2 +22,3 @@ import { createServerRpc } from "./generated/rpc.js"; | ||
| private processExitPromise; | ||
| private negotiatedProtocolVersion; | ||
| /** | ||
@@ -228,3 +229,4 @@ * Typed server-scoped RPC methods. | ||
| /** | ||
| * Verify that the server's protocol version matches the SDK's expected version | ||
| * Verify that the server's protocol version is within the supported range | ||
| * and store the negotiated version. | ||
| */ | ||
@@ -389,2 +391,14 @@ private verifyProtocolVersion; | ||
| /** | ||
| * Handles a v2-style tool.call RPC request from the server. | ||
| * Looks up the session and tool handler, executes it, and returns the result | ||
| * in the v2 response format. | ||
| */ | ||
| private handleToolCallRequestV2; | ||
| /** | ||
| * Handles a v2-style permission.request RPC request from the server. | ||
| */ | ||
| private handlePermissionRequestV2; | ||
| private normalizeToolResultV2; | ||
| private isToolResultObject; | ||
| /** | ||
| * Attempt to reconnect to the server | ||
@@ -391,0 +405,0 @@ */ |
+109
-5
@@ -14,2 +14,3 @@ import { spawn } from "node:child_process"; | ||
| import { CopilotSession } from "./session.js"; | ||
| const MIN_PROTOCOL_VERSION = 2; | ||
| function isZodSchema(value) { | ||
@@ -56,2 +57,3 @@ return value != null && typeof value === "object" && "toJSONSchema" in value && typeof value.toJSONSchema === "function"; | ||
| // Rejects when CLI process exits | ||
| negotiatedProtocolVersion = null; | ||
| /** | ||
@@ -587,6 +589,7 @@ * Typed server-scoped RPC methods. | ||
| /** | ||
| * Verify that the server's protocol version matches the SDK's expected version | ||
| * Verify that the server's protocol version is within the supported range | ||
| * and store the negotiated version. | ||
| */ | ||
| async verifyProtocolVersion() { | ||
| const expectedVersion = getSdkProtocolVersion(); | ||
| const maxVersion = getSdkProtocolVersion(); | ||
| let pingResult; | ||
@@ -601,10 +604,11 @@ if (this.processExitPromise) { | ||
| throw new Error( | ||
| `SDK protocol version mismatch: SDK expects version ${expectedVersion}, but server does not report a protocol version. Please update your server to ensure compatibility.` | ||
| `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.` | ||
| ); | ||
| } | ||
| if (serverVersion !== expectedVersion) { | ||
| if (serverVersion < MIN_PROTOCOL_VERSION || serverVersion > maxVersion) { | ||
| throw new Error( | ||
| `SDK protocol version mismatch: SDK expects version ${expectedVersion}, but server reports version ${serverVersion}. Please update your SDK or server to ensure compatibility.` | ||
| `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.` | ||
| ); | ||
| } | ||
| this.negotiatedProtocolVersion = serverVersion; | ||
| } | ||
@@ -983,2 +987,10 @@ /** | ||
| this.connection.onRequest( | ||
| "tool.call", | ||
| async (params) => await this.handleToolCallRequestV2(params) | ||
| ); | ||
| this.connection.onRequest( | ||
| "permission.request", | ||
| async (params) => await this.handlePermissionRequestV2(params) | ||
| ); | ||
| this.connection.onRequest( | ||
| "userInput.request", | ||
@@ -1055,3 +1067,95 @@ async (params) => await this.handleUserInputRequest(params) | ||
| } | ||
| // ======================================================================== | ||
| // Protocol v2 backward-compatibility adapters | ||
| // ======================================================================== | ||
| /** | ||
| * Handles a v2-style tool.call RPC request from the server. | ||
| * Looks up the session and tool handler, executes it, and returns the result | ||
| * in the v2 response format. | ||
| */ | ||
| async handleToolCallRequestV2(params) { | ||
| if (!params || typeof params.sessionId !== "string" || typeof params.toolCallId !== "string" || typeof params.toolName !== "string") { | ||
| throw new Error("Invalid tool call payload"); | ||
| } | ||
| const session = this.sessions.get(params.sessionId); | ||
| if (!session) { | ||
| throw new Error(`Unknown session ${params.sessionId}`); | ||
| } | ||
| const handler = session.getToolHandler(params.toolName); | ||
| if (!handler) { | ||
| return { | ||
| result: { | ||
| textResultForLlm: `Tool '${params.toolName}' is not supported by this client instance.`, | ||
| resultType: "failure", | ||
| error: `tool '${params.toolName}' not supported`, | ||
| toolTelemetry: {} | ||
| } | ||
| }; | ||
| } | ||
| try { | ||
| const invocation = { | ||
| sessionId: params.sessionId, | ||
| toolCallId: params.toolCallId, | ||
| toolName: params.toolName, | ||
| arguments: params.arguments | ||
| }; | ||
| const result = await handler(params.arguments, invocation); | ||
| return { result: this.normalizeToolResultV2(result) }; | ||
| } catch (error) { | ||
| const message = error instanceof Error ? error.message : String(error); | ||
| return { | ||
| result: { | ||
| textResultForLlm: "Invoking this tool produced an error. Detailed information is not available.", | ||
| resultType: "failure", | ||
| error: message, | ||
| toolTelemetry: {} | ||
| } | ||
| }; | ||
| } | ||
| } | ||
| /** | ||
| * Handles a v2-style permission.request RPC request from the server. | ||
| */ | ||
| async handlePermissionRequestV2(params) { | ||
| if (!params || typeof params.sessionId !== "string" || !params.permissionRequest) { | ||
| throw new Error("Invalid permission request payload"); | ||
| } | ||
| const session = this.sessions.get(params.sessionId); | ||
| if (!session) { | ||
| throw new Error(`Session not found: ${params.sessionId}`); | ||
| } | ||
| try { | ||
| const result = await session._handlePermissionRequestV2(params.permissionRequest); | ||
| return { result }; | ||
| } catch (_error) { | ||
| return { | ||
| result: { | ||
| kind: "denied-no-approval-rule-and-could-not-request-from-user" | ||
| } | ||
| }; | ||
| } | ||
| } | ||
| normalizeToolResultV2(result) { | ||
| if (result === void 0 || result === null) { | ||
| return { | ||
| textResultForLlm: "Tool returned no result", | ||
| resultType: "failure", | ||
| error: "tool returned no result", | ||
| toolTelemetry: {} | ||
| }; | ||
| } | ||
| if (this.isToolResultObject(result)) { | ||
| return result; | ||
| } | ||
| const textResult = typeof result === "string" ? result : JSON.stringify(result); | ||
| return { | ||
| textResultForLlm: textResult, | ||
| resultType: "success", | ||
| toolTelemetry: {} | ||
| }; | ||
| } | ||
| isToolResultObject(value) { | ||
| return typeof value === "object" && value !== null && "textResultForLlm" in value && typeof value.textResultForLlm === "string" && "resultType" in value; | ||
| } | ||
| /** | ||
| * Attempt to reconnect to the server | ||
@@ -1058,0 +1162,0 @@ */ |
+10
-1
@@ -7,3 +7,3 @@ /** | ||
| import { createSessionRpc } from "./generated/rpc.js"; | ||
| import type { MessageOptions, PermissionHandler, SessionEvent, SessionEventHandler, SessionEventType, SessionHooks, Tool, ToolHandler, TypedSessionEventHandler, UserInputHandler, UserInputResponse } from "./types.js"; | ||
| import type { MessageOptions, PermissionHandler, PermissionRequestResult, SessionEvent, SessionEventHandler, SessionEventType, SessionHooks, Tool, ToolHandler, TypedSessionEventHandler, UserInputHandler, UserInputResponse } from "./types.js"; | ||
| /** Assistant message event - the final response from the assistant. */ | ||
@@ -231,2 +231,11 @@ export type AssistantMessageEvent = Extract<SessionEvent, { | ||
| /** | ||
| * Handles a permission request in the v2 protocol format (synchronous RPC). | ||
| * Used as a back-compat adapter when connected to a v2 server. | ||
| * | ||
| * @param request - The permission request data from the CLI | ||
| * @returns A promise that resolves with the permission decision | ||
| * @internal This method is for internal use by the SDK. | ||
| */ | ||
| _handlePermissionRequestV2(request: unknown): Promise<PermissionRequestResult>; | ||
| /** | ||
| * Handles a user input request from the Copilot CLI. | ||
@@ -233,0 +242,0 @@ * |
+21
-0
@@ -323,2 +323,23 @@ import { ConnectionError, ResponseError } from "vscode-jsonrpc/node"; | ||
| /** | ||
| * Handles a permission request in the v2 protocol format (synchronous RPC). | ||
| * Used as a back-compat adapter when connected to a v2 server. | ||
| * | ||
| * @param request - The permission request data from the CLI | ||
| * @returns A promise that resolves with the permission decision | ||
| * @internal This method is for internal use by the SDK. | ||
| */ | ||
| async _handlePermissionRequestV2(request) { | ||
| if (!this.permissionHandler) { | ||
| return { kind: "denied-no-approval-rule-and-could-not-request-from-user" }; | ||
| } | ||
| try { | ||
| const result = await this.permissionHandler(request, { | ||
| sessionId: this.sessionId | ||
| }); | ||
| return result; | ||
| } catch (_error) { | ||
| return { kind: "denied-no-approval-rule-and-could-not-request-from-user" }; | ||
| } | ||
| } | ||
| /** | ||
| * Handles a user input request from the Copilot CLI. | ||
@@ -325,0 +346,0 @@ * |
+1
-1
@@ -7,3 +7,3 @@ { | ||
| }, | ||
| "version": "0.1.31", | ||
| "version": "0.1.32", | ||
| "description": "TypeScript SDK for programmatic control of GitHub Copilot CLI via JSON-RPC", | ||
@@ -10,0 +10,0 @@ "main": "./dist/index.js", |
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
228795
2.46%6519
2.32%