@github/copilot-sdk 0.1.33-preview.2 → 0.1.33-preview.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +181 -5
- package/dist/cjs/client.js +1317 -0
- package/dist/cjs/extension.js +45 -0
- package/dist/cjs/generated/rpc.js +123 -0
- package/dist/cjs/generated/session-events.js +16 -0
- package/dist/cjs/index.js +38 -0
- package/dist/cjs/package.json +1 -0
- package/dist/cjs/sdkProtocolVersion.js +33 -0
- package/dist/cjs/session.js +616 -0
- package/dist/cjs/telemetry.js +35 -0
- package/dist/cjs/types.js +49 -0
- package/dist/client.d.ts +2 -0
- package/dist/client.js +109 -9
- package/dist/generated/rpc.d.ts +446 -0
- package/dist/generated/rpc.js +36 -1
- package/dist/generated/session-events.d.ts +393 -14
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -1
- package/dist/session.d.ts +32 -3
- package/dist/session.js +60 -6
- package/dist/telemetry.d.ts +14 -0
- package/dist/telemetry.js +11 -0
- package/dist/types.d.ts +133 -2
- package/dist/types.js +15 -0
- package/package.json +19 -7
package/dist/client.d.ts
CHANGED
|
@@ -47,6 +47,7 @@ export declare class CopilotClient {
|
|
|
47
47
|
private isExternalServer;
|
|
48
48
|
private forceStopping;
|
|
49
49
|
private onListModels?;
|
|
50
|
+
private onGetTraceContext?;
|
|
50
51
|
private modelsCache;
|
|
51
52
|
private modelsCacheLock;
|
|
52
53
|
private sessionLifecycleHandlers;
|
|
@@ -422,6 +423,7 @@ export declare class CopilotClient {
|
|
|
422
423
|
private handleSessionLifecycleNotification;
|
|
423
424
|
private handleUserInputRequest;
|
|
424
425
|
private handleHooksInvoke;
|
|
426
|
+
private handleSystemMessageTransform;
|
|
425
427
|
/**
|
|
426
428
|
* Handles a v2-style tool.call RPC request from the server.
|
|
427
429
|
* Looks up the session and tool handler, executes it, and returns the result
|
package/dist/client.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { spawn } from "node:child_process";
|
|
2
2
|
import { randomUUID } from "node:crypto";
|
|
3
3
|
import { existsSync } from "node:fs";
|
|
4
|
+
import { createRequire } from "node:module";
|
|
4
5
|
import { Socket } from "node:net";
|
|
5
6
|
import { dirname, join } from "node:path";
|
|
6
7
|
import { fileURLToPath } from "node:url";
|
|
@@ -12,6 +13,7 @@ import {
|
|
|
12
13
|
import { createServerRpc } from "./generated/rpc.js";
|
|
13
14
|
import { getSdkProtocolVersion } from "./sdkProtocolVersion.js";
|
|
14
15
|
import { CopilotSession, NO_RESULT_PERMISSION_V2_ERROR } from "./session.js";
|
|
16
|
+
import { getTraceContext } from "./telemetry.js";
|
|
15
17
|
const MIN_PROTOCOL_VERSION = 2;
|
|
16
18
|
function isZodSchema(value) {
|
|
17
19
|
return value != null && typeof value === "object" && "toJSONSchema" in value && typeof value.toJSONSchema === "function";
|
|
@@ -23,6 +25,30 @@ function toJsonSchema(parameters) {
|
|
|
23
25
|
}
|
|
24
26
|
return parameters;
|
|
25
27
|
}
|
|
28
|
+
function extractTransformCallbacks(systemMessage) {
|
|
29
|
+
if (!systemMessage || systemMessage.mode !== "customize" || !systemMessage.sections) {
|
|
30
|
+
return { wirePayload: systemMessage, transformCallbacks: void 0 };
|
|
31
|
+
}
|
|
32
|
+
const transformCallbacks = /* @__PURE__ */ new Map();
|
|
33
|
+
const wireSections = {};
|
|
34
|
+
for (const [sectionId, override] of Object.entries(systemMessage.sections)) {
|
|
35
|
+
if (!override) continue;
|
|
36
|
+
if (typeof override.action === "function") {
|
|
37
|
+
transformCallbacks.set(sectionId, override.action);
|
|
38
|
+
wireSections[sectionId] = { action: "transform" };
|
|
39
|
+
} else {
|
|
40
|
+
wireSections[sectionId] = { action: override.action, content: override.content };
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
if (transformCallbacks.size === 0) {
|
|
44
|
+
return { wirePayload: systemMessage, transformCallbacks: void 0 };
|
|
45
|
+
}
|
|
46
|
+
const wirePayload = {
|
|
47
|
+
...systemMessage,
|
|
48
|
+
sections: wireSections
|
|
49
|
+
};
|
|
50
|
+
return { wirePayload, transformCallbacks };
|
|
51
|
+
}
|
|
26
52
|
function getNodeExecPath() {
|
|
27
53
|
if (process.versions.bun) {
|
|
28
54
|
return "node";
|
|
@@ -30,9 +56,22 @@ function getNodeExecPath() {
|
|
|
30
56
|
return process.execPath;
|
|
31
57
|
}
|
|
32
58
|
function getBundledCliPath() {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
59
|
+
if (typeof import.meta.resolve === "function") {
|
|
60
|
+
const sdkUrl = import.meta.resolve("@github/copilot/sdk");
|
|
61
|
+
const sdkPath = fileURLToPath(sdkUrl);
|
|
62
|
+
return join(dirname(dirname(sdkPath)), "index.js");
|
|
63
|
+
}
|
|
64
|
+
const req = createRequire(__filename);
|
|
65
|
+
const searchPaths = req.resolve.paths("@github/copilot") ?? [];
|
|
66
|
+
for (const base of searchPaths) {
|
|
67
|
+
const candidate = join(base, "@github", "copilot", "index.js");
|
|
68
|
+
if (existsSync(candidate)) {
|
|
69
|
+
return candidate;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
throw new Error(
|
|
73
|
+
`Could not find @github/copilot package. Searched ${searchPaths.length} paths. Ensure it is installed, or pass cliPath/cliUrl to CopilotClient.`
|
|
74
|
+
);
|
|
36
75
|
}
|
|
37
76
|
class CopilotClient {
|
|
38
77
|
cliProcess = null;
|
|
@@ -48,6 +87,7 @@ class CopilotClient {
|
|
|
48
87
|
isExternalServer = false;
|
|
49
88
|
forceStopping = false;
|
|
50
89
|
onListModels;
|
|
90
|
+
onGetTraceContext;
|
|
51
91
|
modelsCache = null;
|
|
52
92
|
modelsCacheLock = Promise.resolve();
|
|
53
93
|
sessionLifecycleHandlers = /* @__PURE__ */ new Set();
|
|
@@ -114,6 +154,7 @@ class CopilotClient {
|
|
|
114
154
|
this.isExternalServer = true;
|
|
115
155
|
}
|
|
116
156
|
this.onListModels = options.onListModels;
|
|
157
|
+
this.onGetTraceContext = options.onGetTraceContext;
|
|
117
158
|
this.options = {
|
|
118
159
|
cliPath: options.cliUrl ? void 0 : options.cliPath || getBundledCliPath(),
|
|
119
160
|
cliArgs: options.cliArgs ?? [],
|
|
@@ -129,7 +170,8 @@ class CopilotClient {
|
|
|
129
170
|
env: options.env ?? process.env,
|
|
130
171
|
githubToken: options.githubToken,
|
|
131
172
|
// Default useLoggedInUser to false when githubToken is provided, otherwise true
|
|
132
|
-
useLoggedInUser: options.useLoggedInUser ?? (options.githubToken ? false : true)
|
|
173
|
+
useLoggedInUser: options.useLoggedInUser ?? (options.githubToken ? false : true),
|
|
174
|
+
telemetry: options.telemetry
|
|
133
175
|
};
|
|
134
176
|
}
|
|
135
177
|
/**
|
|
@@ -382,7 +424,12 @@ class CopilotClient {
|
|
|
382
424
|
}
|
|
383
425
|
}
|
|
384
426
|
const sessionId = config.sessionId ?? randomUUID();
|
|
385
|
-
const session = new CopilotSession(
|
|
427
|
+
const session = new CopilotSession(
|
|
428
|
+
sessionId,
|
|
429
|
+
this.connection,
|
|
430
|
+
void 0,
|
|
431
|
+
this.onGetTraceContext
|
|
432
|
+
);
|
|
386
433
|
session.registerTools(config.tools);
|
|
387
434
|
session.registerPermissionHandler(config.onPermissionRequest);
|
|
388
435
|
if (config.onUserInputRequest) {
|
|
@@ -391,12 +438,19 @@ class CopilotClient {
|
|
|
391
438
|
if (config.hooks) {
|
|
392
439
|
session.registerHooks(config.hooks);
|
|
393
440
|
}
|
|
441
|
+
const { wirePayload: wireSystemMessage, transformCallbacks } = extractTransformCallbacks(
|
|
442
|
+
config.systemMessage
|
|
443
|
+
);
|
|
444
|
+
if (transformCallbacks) {
|
|
445
|
+
session.registerTransformCallbacks(transformCallbacks);
|
|
446
|
+
}
|
|
394
447
|
if (config.onEvent) {
|
|
395
448
|
session.on(config.onEvent);
|
|
396
449
|
}
|
|
397
450
|
this.sessions.set(sessionId, session);
|
|
398
451
|
try {
|
|
399
452
|
const response = await this.connection.sendRequest("session.create", {
|
|
453
|
+
...await getTraceContext(this.onGetTraceContext),
|
|
400
454
|
model: config.model,
|
|
401
455
|
sessionId,
|
|
402
456
|
clientName: config.clientName,
|
|
@@ -408,7 +462,7 @@ class CopilotClient {
|
|
|
408
462
|
overridesBuiltInTool: tool.overridesBuiltInTool,
|
|
409
463
|
skipPermission: tool.skipPermission
|
|
410
464
|
})),
|
|
411
|
-
systemMessage:
|
|
465
|
+
systemMessage: wireSystemMessage,
|
|
412
466
|
availableTools: config.availableTools,
|
|
413
467
|
excludedTools: config.excludedTools,
|
|
414
468
|
provider: config.provider,
|
|
@@ -471,7 +525,12 @@ class CopilotClient {
|
|
|
471
525
|
throw new Error("Client not connected. Call start() first.");
|
|
472
526
|
}
|
|
473
527
|
}
|
|
474
|
-
const session = new CopilotSession(
|
|
528
|
+
const session = new CopilotSession(
|
|
529
|
+
sessionId,
|
|
530
|
+
this.connection,
|
|
531
|
+
void 0,
|
|
532
|
+
this.onGetTraceContext
|
|
533
|
+
);
|
|
475
534
|
session.registerTools(config.tools);
|
|
476
535
|
session.registerPermissionHandler(config.onPermissionRequest);
|
|
477
536
|
if (config.onUserInputRequest) {
|
|
@@ -480,17 +539,24 @@ class CopilotClient {
|
|
|
480
539
|
if (config.hooks) {
|
|
481
540
|
session.registerHooks(config.hooks);
|
|
482
541
|
}
|
|
542
|
+
const { wirePayload: wireSystemMessage, transformCallbacks } = extractTransformCallbacks(
|
|
543
|
+
config.systemMessage
|
|
544
|
+
);
|
|
545
|
+
if (transformCallbacks) {
|
|
546
|
+
session.registerTransformCallbacks(transformCallbacks);
|
|
547
|
+
}
|
|
483
548
|
if (config.onEvent) {
|
|
484
549
|
session.on(config.onEvent);
|
|
485
550
|
}
|
|
486
551
|
this.sessions.set(sessionId, session);
|
|
487
552
|
try {
|
|
488
553
|
const response = await this.connection.sendRequest("session.resume", {
|
|
554
|
+
...await getTraceContext(this.onGetTraceContext),
|
|
489
555
|
sessionId,
|
|
490
556
|
clientName: config.clientName,
|
|
491
557
|
model: config.model,
|
|
492
558
|
reasoningEffort: config.reasoningEffort,
|
|
493
|
-
systemMessage:
|
|
559
|
+
systemMessage: wireSystemMessage,
|
|
494
560
|
availableTools: config.availableTools,
|
|
495
561
|
excludedTools: config.excludedTools,
|
|
496
562
|
tools: config.tools?.map((tool) => ({
|
|
@@ -829,6 +895,22 @@ class CopilotClient {
|
|
|
829
895
|
"Path to Copilot CLI is required. Please provide it via the cliPath option, or use cliUrl to rely on a remote CLI."
|
|
830
896
|
);
|
|
831
897
|
}
|
|
898
|
+
if (this.options.telemetry) {
|
|
899
|
+
const t = this.options.telemetry;
|
|
900
|
+
envWithoutNodeDebug.COPILOT_OTEL_ENABLED = "true";
|
|
901
|
+
if (t.otlpEndpoint !== void 0)
|
|
902
|
+
envWithoutNodeDebug.OTEL_EXPORTER_OTLP_ENDPOINT = t.otlpEndpoint;
|
|
903
|
+
if (t.filePath !== void 0)
|
|
904
|
+
envWithoutNodeDebug.COPILOT_OTEL_FILE_EXPORTER_PATH = t.filePath;
|
|
905
|
+
if (t.exporterType !== void 0)
|
|
906
|
+
envWithoutNodeDebug.COPILOT_OTEL_EXPORTER_TYPE = t.exporterType;
|
|
907
|
+
if (t.sourceName !== void 0)
|
|
908
|
+
envWithoutNodeDebug.COPILOT_OTEL_SOURCE_NAME = t.sourceName;
|
|
909
|
+
if (t.captureContent !== void 0)
|
|
910
|
+
envWithoutNodeDebug.OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT = String(
|
|
911
|
+
t.captureContent
|
|
912
|
+
);
|
|
913
|
+
}
|
|
832
914
|
if (!existsSync(this.options.cliPath)) {
|
|
833
915
|
throw new Error(
|
|
834
916
|
`Copilot CLI not found at ${this.options.cliPath}. Ensure @github/copilot is installed.`
|
|
@@ -1032,6 +1114,10 @@ stderr: ${stderrOutput}`
|
|
|
1032
1114
|
"hooks.invoke",
|
|
1033
1115
|
async (params) => await this.handleHooksInvoke(params)
|
|
1034
1116
|
);
|
|
1117
|
+
this.connection.onRequest(
|
|
1118
|
+
"systemMessage.transform",
|
|
1119
|
+
async (params) => await this.handleSystemMessageTransform(params)
|
|
1120
|
+
);
|
|
1035
1121
|
this.connection.onClose(() => {
|
|
1036
1122
|
this.state = "disconnected";
|
|
1037
1123
|
});
|
|
@@ -1095,6 +1181,16 @@ stderr: ${stderrOutput}`
|
|
|
1095
1181
|
const output = await session._handleHooksInvoke(params.hookType, params.input);
|
|
1096
1182
|
return { output };
|
|
1097
1183
|
}
|
|
1184
|
+
async handleSystemMessageTransform(params) {
|
|
1185
|
+
if (!params || typeof params.sessionId !== "string" || !params.sections || typeof params.sections !== "object") {
|
|
1186
|
+
throw new Error("Invalid systemMessage.transform payload");
|
|
1187
|
+
}
|
|
1188
|
+
const session = this.sessions.get(params.sessionId);
|
|
1189
|
+
if (!session) {
|
|
1190
|
+
throw new Error(`Session not found: ${params.sessionId}`);
|
|
1191
|
+
}
|
|
1192
|
+
return await session._handleSystemMessageTransform(params.sections);
|
|
1193
|
+
}
|
|
1098
1194
|
// ========================================================================
|
|
1099
1195
|
// Protocol v2 backward-compatibility adapters
|
|
1100
1196
|
// ========================================================================
|
|
@@ -1123,11 +1219,15 @@ stderr: ${stderrOutput}`
|
|
|
1123
1219
|
};
|
|
1124
1220
|
}
|
|
1125
1221
|
try {
|
|
1222
|
+
const traceparent = params.traceparent;
|
|
1223
|
+
const tracestate = params.tracestate;
|
|
1126
1224
|
const invocation = {
|
|
1127
1225
|
sessionId: params.sessionId,
|
|
1128
1226
|
toolCallId: params.toolCallId,
|
|
1129
1227
|
toolName: params.toolName,
|
|
1130
|
-
arguments: params.arguments
|
|
1228
|
+
arguments: params.arguments,
|
|
1229
|
+
traceparent,
|
|
1230
|
+
tracestate
|
|
1131
1231
|
};
|
|
1132
1232
|
const result = await handler(params.arguments, invocation);
|
|
1133
1233
|
return { result: this.normalizeToolResultV2(result) };
|