@github/copilot-language-server 1.542.0 → 1.544.0
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/main.js +1011 -1006
- package/dist/node_modules/@github/copilot-sdk/dist/cjs/cliVersion.js +31 -0
- package/dist/node_modules/@github/copilot-sdk/dist/cjs/client.js +244 -108
- package/dist/node_modules/@github/copilot-sdk/dist/cjs/extension.js +3 -1
- package/dist/node_modules/@github/copilot-sdk/dist/cjs/ffiRuntimeHost.js +14 -19
- package/dist/node_modules/@github/copilot-sdk/dist/cjs/generated/rpc.js +293 -22
- package/dist/node_modules/@github/copilot-sdk/dist/cjs/index.js +2 -0
- package/dist/node_modules/@github/copilot-sdk/dist/cjs/runtimeArtifacts.js +254 -0
- package/dist/node_modules/@github/copilot-sdk/dist/cjs/session.js +144 -16
- package/dist/node_modules/@github/copilot-sdk/dist/cjs/types.js +8 -0
- package/dist/node_modules/@github/copilot-sdk/package.json +103 -88
- package/package.json +14 -14
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var runtimeArtifacts_exports = {};
|
|
20
|
+
__export(runtimeArtifacts_exports, {
|
|
21
|
+
RUNTIME_PLATFORMS: () => RUNTIME_PLATFORMS,
|
|
22
|
+
defaultRuntimeCacheRoot: () => defaultRuntimeCacheRoot,
|
|
23
|
+
ensureRuntimeBundle: () => ensureRuntimeBundle,
|
|
24
|
+
getRuntimePackageName: () => getRuntimePackageName,
|
|
25
|
+
getRuntimePlatform: () => getRuntimePlatform,
|
|
26
|
+
getRuntimeReleaseAssetName: () => getRuntimeReleaseAssetName,
|
|
27
|
+
materializeRuntimeBundle: () => materializeRuntimeBundle,
|
|
28
|
+
resolvePackageRoot: () => resolvePackageRoot,
|
|
29
|
+
validateFile: () => validateFile
|
|
30
|
+
});
|
|
31
|
+
module.exports = __toCommonJS(runtimeArtifacts_exports);
|
|
32
|
+
var import_node_fs = require("node:fs");
|
|
33
|
+
var import_node_crypto = require("node:crypto");
|
|
34
|
+
var import_node_module = require("node:module");
|
|
35
|
+
var import_node_os = require("node:os");
|
|
36
|
+
var import_node_path = require("node:path");
|
|
37
|
+
var import_cliVersion = require("./cliVersion.js");
|
|
38
|
+
const import_meta = {};
|
|
39
|
+
const require2 = (0, import_node_module.createRequire)(typeof __filename === "string" ? __filename : import_meta.url);
|
|
40
|
+
const RUNTIME_PLATFORMS = [
|
|
41
|
+
"darwin-arm64",
|
|
42
|
+
"darwin-x64",
|
|
43
|
+
"linux-arm64",
|
|
44
|
+
"linux-x64",
|
|
45
|
+
"linuxmusl-arm64",
|
|
46
|
+
"linuxmusl-x64",
|
|
47
|
+
"win32-arm64",
|
|
48
|
+
"win32-x64"
|
|
49
|
+
];
|
|
50
|
+
const EXCLUDED_TOP_LEVEL = /* @__PURE__ */ new Set([
|
|
51
|
+
"app.js",
|
|
52
|
+
"assets",
|
|
53
|
+
"changelog.json",
|
|
54
|
+
"copilot",
|
|
55
|
+
"copilot.exe",
|
|
56
|
+
"foundry-local-sdk",
|
|
57
|
+
"index.js",
|
|
58
|
+
"LICENSE.md",
|
|
59
|
+
"napi-oop-runtime",
|
|
60
|
+
"npm-loader.js",
|
|
61
|
+
"package.json",
|
|
62
|
+
"pvrecorder",
|
|
63
|
+
"queries",
|
|
64
|
+
"README.md",
|
|
65
|
+
"sea-loader.js",
|
|
66
|
+
"webview"
|
|
67
|
+
]);
|
|
68
|
+
function validateFile(path, label) {
|
|
69
|
+
if (!(0, import_node_fs.existsSync)(path)) {
|
|
70
|
+
throw new Error(`${label} not found at ${path}.`);
|
|
71
|
+
}
|
|
72
|
+
if ((0, import_node_fs.statSync)(path).size === 0) {
|
|
73
|
+
throw new Error(`${label} at ${path} is empty.`);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
function validateRuntimeBundle(wrapper, runtimeNode) {
|
|
77
|
+
validateFile(wrapper, "Copilot runtime wrapper");
|
|
78
|
+
validateFile(runtimeNode, "Copilot runtime.node");
|
|
79
|
+
}
|
|
80
|
+
function isExcluded(relativePath) {
|
|
81
|
+
const parts = relativePath.split(import_node_path.sep);
|
|
82
|
+
const topLevel = parts[0];
|
|
83
|
+
const fileName = parts.at(-1) ?? "";
|
|
84
|
+
return EXCLUDED_TOP_LEVEL.has(topLevel) || /^tree-sitter.*\.wasm$/.test(topLevel) || /^voice-.*\.js$/.test(topLevel) || fileName === "cli-native.node" || parts.includes("mediaremote-adapter") || fileName.startsWith("copilot-runtime-bin");
|
|
85
|
+
}
|
|
86
|
+
function collectRuntimeAssets(sources) {
|
|
87
|
+
const assets = [];
|
|
88
|
+
const visit = (directory) => {
|
|
89
|
+
for (const entry of (0, import_node_fs.readdirSync)(directory, { withFileTypes: true })) {
|
|
90
|
+
const source = (0, import_node_path.join)(directory, entry.name);
|
|
91
|
+
const sourceRelative = (0, import_node_path.relative)(sources.packageRoot, source);
|
|
92
|
+
if (isExcluded(sourceRelative)) {
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
if (entry.isDirectory()) {
|
|
96
|
+
visit(source);
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
if (!entry.isFile() && !entry.isSymbolicLink()) {
|
|
100
|
+
continue;
|
|
101
|
+
}
|
|
102
|
+
const parts = sourceRelative.split(import_node_path.sep);
|
|
103
|
+
if (parts[0] === "prebuilds") {
|
|
104
|
+
if (parts[1] !== sources.platform || parts.length < 3) {
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
assets.push({ source, relativePath: sourceRelative });
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
visit(sources.packageRoot);
|
|
112
|
+
return assets.sort((left, right) => left.relativePath.localeCompare(right.relativePath));
|
|
113
|
+
}
|
|
114
|
+
function sourceFingerprint(assets) {
|
|
115
|
+
const hash = (0, import_node_crypto.createHash)("sha256");
|
|
116
|
+
for (const asset of assets) {
|
|
117
|
+
const stat = (0, import_node_fs.lstatSync)(asset.source);
|
|
118
|
+
hash.update(asset.relativePath).update("\0");
|
|
119
|
+
hash.update(`${stat.size}:${stat.mtimeMs}`).update("\0");
|
|
120
|
+
}
|
|
121
|
+
return hash.digest("hex").slice(0, 20);
|
|
122
|
+
}
|
|
123
|
+
function makeExecutable(path) {
|
|
124
|
+
if (process.platform === "win32") {
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
const mode = (0, import_node_fs.statSync)(path).mode;
|
|
128
|
+
if ((mode & 73) === 0) {
|
|
129
|
+
(0, import_node_fs.chmodSync)(path, mode | 73);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
function defaultRuntimeCacheRoot(platform = process.platform, home = (0, import_node_os.homedir)(), environment = process.env) {
|
|
133
|
+
const cacheDirectory = platform === "win32" ? environment.LOCALAPPDATA ?? (0, import_node_path.join)(home, "AppData", "Local") : platform === "darwin" ? (0, import_node_path.join)(home, "Library", "Caches") : environment.XDG_CACHE_HOME ?? (0, import_node_path.join)(home, ".cache");
|
|
134
|
+
return (0, import_node_path.join)(cacheDirectory, "github-copilot-sdk", "runtime");
|
|
135
|
+
}
|
|
136
|
+
function materializeRuntimeBundle(sources, cacheRoot = defaultRuntimeCacheRoot(), cacheKey = `${sources.platform}-${sourceFingerprint(collectRuntimeAssets(sources))}`) {
|
|
137
|
+
const assets = collectRuntimeAssets(sources);
|
|
138
|
+
const wrapperName = sources.platform.startsWith("win32") ? "copilot-runtime.exe" : "copilot-runtime";
|
|
139
|
+
const prebuildDir = (0, import_node_path.join)("prebuilds", sources.platform);
|
|
140
|
+
const wrapperRelative = (0, import_node_path.join)(prebuildDir, wrapperName);
|
|
141
|
+
const runtimeNodeRelative = (0, import_node_path.join)(prebuildDir, "runtime.node");
|
|
142
|
+
const sourceWrapper = assets.find((asset) => asset.relativePath === wrapperRelative)?.source;
|
|
143
|
+
const sourceRuntimeNode = assets.find(
|
|
144
|
+
(asset) => asset.relativePath === runtimeNodeRelative
|
|
145
|
+
)?.source;
|
|
146
|
+
validateRuntimeBundle(sourceWrapper ?? "", sourceRuntimeNode ?? "");
|
|
147
|
+
const installDir = (0, import_node_path.join)(cacheRoot, cacheKey);
|
|
148
|
+
const installedWrapper = (0, import_node_path.join)(installDir, wrapperRelative);
|
|
149
|
+
const installedRuntimeNode = (0, import_node_path.join)(installDir, runtimeNodeRelative);
|
|
150
|
+
if ((0, import_node_fs.existsSync)(installDir)) {
|
|
151
|
+
validateRuntimeBundle(installedWrapper, installedRuntimeNode);
|
|
152
|
+
makeExecutable(installedWrapper);
|
|
153
|
+
return installedWrapper;
|
|
154
|
+
}
|
|
155
|
+
(0, import_node_fs.mkdirSync)(cacheRoot, { recursive: true });
|
|
156
|
+
const stagingDir = (0, import_node_fs.mkdtempSync)((0, import_node_path.join)(cacheRoot, ".runtime-"));
|
|
157
|
+
try {
|
|
158
|
+
for (const asset of assets) {
|
|
159
|
+
const destination = (0, import_node_path.join)(stagingDir, asset.relativePath);
|
|
160
|
+
(0, import_node_fs.mkdirSync)((0, import_node_path.dirname)(destination), { recursive: true });
|
|
161
|
+
(0, import_node_fs.copyFileSync)(asset.source, destination);
|
|
162
|
+
}
|
|
163
|
+
const stagedWrapper = (0, import_node_path.join)(stagingDir, wrapperRelative);
|
|
164
|
+
makeExecutable(stagedWrapper);
|
|
165
|
+
(0, import_node_fs.renameSync)(stagingDir, installDir);
|
|
166
|
+
} catch (error) {
|
|
167
|
+
if (!(0, import_node_fs.existsSync)(installDir)) {
|
|
168
|
+
throw error;
|
|
169
|
+
}
|
|
170
|
+
validateRuntimeBundle(installedWrapper, installedRuntimeNode);
|
|
171
|
+
} finally {
|
|
172
|
+
(0, import_node_fs.rmSync)(stagingDir, { recursive: true, force: true });
|
|
173
|
+
}
|
|
174
|
+
return installedWrapper;
|
|
175
|
+
}
|
|
176
|
+
function isMusl() {
|
|
177
|
+
if (process.platform !== "linux") {
|
|
178
|
+
return false;
|
|
179
|
+
}
|
|
180
|
+
const report = process.report?.getReport();
|
|
181
|
+
return report?.header?.glibcVersionRuntime === void 0;
|
|
182
|
+
}
|
|
183
|
+
function getRuntimePlatform(platform = process.platform, arch = process.arch, musl = isMusl()) {
|
|
184
|
+
if (arch !== "x64" && arch !== "arm64") {
|
|
185
|
+
throw new Error(`Unsupported Copilot CLI architecture: ${arch}.`);
|
|
186
|
+
}
|
|
187
|
+
if (platform === "linux") {
|
|
188
|
+
return `${musl ? "linuxmusl" : "linux"}-${arch}`;
|
|
189
|
+
}
|
|
190
|
+
if (platform === "darwin" || platform === "win32") {
|
|
191
|
+
return `${platform}-${arch}`;
|
|
192
|
+
}
|
|
193
|
+
throw new Error(`Unsupported Copilot CLI platform: ${platform}-${arch}.`);
|
|
194
|
+
}
|
|
195
|
+
function getRuntimeReleaseAssetName(version, platform) {
|
|
196
|
+
return `github-copilot-${version}-${platform}.tgz`;
|
|
197
|
+
}
|
|
198
|
+
function getRuntimePackageName(platform) {
|
|
199
|
+
return `@github/copilot-sdk-${platform}`;
|
|
200
|
+
}
|
|
201
|
+
function resolvePackageRoot(packageName, searchPaths = require2.resolve.paths(packageName) ?? []) {
|
|
202
|
+
return searchPaths.map((base) => (0, import_node_path.join)(base, ...packageName.split("/"))).find((candidate) => (0, import_node_fs.existsSync)((0, import_node_path.join)(candidate, "package.json")));
|
|
203
|
+
}
|
|
204
|
+
async function ensureRuntimeBundle(version, options = {}) {
|
|
205
|
+
const platform = options.platform ?? getRuntimePlatform();
|
|
206
|
+
if (import_cliVersion.COPILOT_CLI_USE_NPM_PACKAGE) {
|
|
207
|
+
const packageName2 = `@github/copilot-${platform}`;
|
|
208
|
+
const packageRoot2 = resolvePackageRoot(packageName2, options.packageSearchPaths);
|
|
209
|
+
if (!packageRoot2) {
|
|
210
|
+
throw new Error(`Could not resolve ${packageName2} for Copilot CLI ${version}.`);
|
|
211
|
+
}
|
|
212
|
+
validateFile(
|
|
213
|
+
(0, import_node_path.join)(packageRoot2, "prebuilds", platform, "runtime.node"),
|
|
214
|
+
"Copilot runtime.node"
|
|
215
|
+
);
|
|
216
|
+
return materializeRuntimeBundle(
|
|
217
|
+
{ packageRoot: packageRoot2, platform },
|
|
218
|
+
options.cacheRoot,
|
|
219
|
+
`${version}-${platform}`
|
|
220
|
+
);
|
|
221
|
+
}
|
|
222
|
+
const packageName = getRuntimePackageName(platform);
|
|
223
|
+
const packageRoot = resolvePackageRoot(packageName, options.packageSearchPaths);
|
|
224
|
+
if (!packageRoot) {
|
|
225
|
+
throw new Error(
|
|
226
|
+
`Could not resolve ${packageName}. Reinstall @github/copilot-sdk so its platform package is installed.`
|
|
227
|
+
);
|
|
228
|
+
}
|
|
229
|
+
const wrapperName = platform.startsWith("win32") ? "copilot-runtime.exe" : "copilot-runtime";
|
|
230
|
+
const prebuildDir = (0, import_node_path.join)(packageRoot, "prebuilds", platform);
|
|
231
|
+
const wrapper = (0, import_node_path.join)(prebuildDir, wrapperName);
|
|
232
|
+
try {
|
|
233
|
+
validateRuntimeBundle(wrapper, (0, import_node_path.join)(prebuildDir, "runtime.node"));
|
|
234
|
+
} catch (error) {
|
|
235
|
+
throw new Error(
|
|
236
|
+
`${packageName} is missing required Copilot CLI runtime files. Reinstall @github/copilot-sdk.`,
|
|
237
|
+
{ cause: error }
|
|
238
|
+
);
|
|
239
|
+
}
|
|
240
|
+
makeExecutable(wrapper);
|
|
241
|
+
return wrapper;
|
|
242
|
+
}
|
|
243
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
244
|
+
0 && (module.exports = {
|
|
245
|
+
RUNTIME_PLATFORMS,
|
|
246
|
+
defaultRuntimeCacheRoot,
|
|
247
|
+
ensureRuntimeBundle,
|
|
248
|
+
getRuntimePackageName,
|
|
249
|
+
getRuntimePlatform,
|
|
250
|
+
getRuntimeReleaseAssetName,
|
|
251
|
+
materializeRuntimeBundle,
|
|
252
|
+
resolvePackageRoot,
|
|
253
|
+
validateFile
|
|
254
|
+
});
|
|
@@ -241,6 +241,7 @@ class CopilotSession {
|
|
|
241
241
|
this.traceContextProvider = traceContextProvider;
|
|
242
242
|
this.mcpAuthHandler = options?.mcpAuthHandler;
|
|
243
243
|
this.managedSettingsEnabled = options?.managedSettingsEnabled === true;
|
|
244
|
+
this.onDisconnected = options?.onDisconnected;
|
|
244
245
|
}
|
|
245
246
|
sessionId;
|
|
246
247
|
connection;
|
|
@@ -248,6 +249,7 @@ class CopilotSession {
|
|
|
248
249
|
eventHandlers = /* @__PURE__ */ new Set();
|
|
249
250
|
typedEventHandlers = /* @__PURE__ */ new Map();
|
|
250
251
|
toolHandlers = /* @__PURE__ */ new Map();
|
|
252
|
+
pendingExternalTools = /* @__PURE__ */ new Map();
|
|
251
253
|
canvases = /* @__PURE__ */ new Map();
|
|
252
254
|
bearerTokenProviders = /* @__PURE__ */ new Map();
|
|
253
255
|
commandHandlers = /* @__PURE__ */ new Map();
|
|
@@ -267,6 +269,8 @@ class CopilotSession {
|
|
|
267
269
|
_capabilities = {};
|
|
268
270
|
openCanvasInstances = [];
|
|
269
271
|
disconnected = false;
|
|
272
|
+
disconnecting = false;
|
|
273
|
+
onDisconnected;
|
|
270
274
|
/** @internal Client session API handlers, populated by CopilotClient during create/resume. */
|
|
271
275
|
clientSessionApis = {};
|
|
272
276
|
/**
|
|
@@ -281,14 +285,18 @@ class CopilotSession {
|
|
|
281
285
|
const name = typeof nameOrHandle === "string" ? nameOrHandle : (0, import_factory.getFactoryDefinition)(nameOrHandle).meta.name;
|
|
282
286
|
if (options?.resumeFromRunId !== void 0) {
|
|
283
287
|
return this.factory.resume(options.resumeFromRunId, {
|
|
284
|
-
limits: options.limits
|
|
288
|
+
limits: options.limits,
|
|
289
|
+
notifyOnComplete: options.notifyOnComplete,
|
|
290
|
+
logPhaseNames: options.logPhaseNames
|
|
285
291
|
});
|
|
286
292
|
}
|
|
287
293
|
const envelope = await this.rpc.factory.run({
|
|
288
294
|
name,
|
|
289
295
|
args: options?.args === void 0 ? {} : options.args,
|
|
290
296
|
options: {
|
|
291
|
-
limits: options?.limits
|
|
297
|
+
limits: options?.limits,
|
|
298
|
+
notifyOnComplete: options?.notifyOnComplete,
|
|
299
|
+
logPhaseNames: options?.logPhaseNames
|
|
292
300
|
}
|
|
293
301
|
});
|
|
294
302
|
return this.settleFactoryRun(envelope);
|
|
@@ -299,7 +307,9 @@ class CopilotSession {
|
|
|
299
307
|
try {
|
|
300
308
|
response = await this.rpc.factory.resume({
|
|
301
309
|
runId,
|
|
302
|
-
limits: options?.limits
|
|
310
|
+
limits: options?.limits,
|
|
311
|
+
notifyOnComplete: options?.notifyOnComplete,
|
|
312
|
+
logPhaseNames: options?.logPhaseNames
|
|
303
313
|
});
|
|
304
314
|
} catch (error) {
|
|
305
315
|
if (error instanceof import_node.ResponseError && typeof error.data === "object" && error.data !== null) {
|
|
@@ -314,7 +324,10 @@ class CopilotSession {
|
|
|
314
324
|
}),
|
|
315
325
|
getRun: async (runId) => this.rpc.factory.getRun({ runId }),
|
|
316
326
|
waitForRun: (runId, options) => this.waitForFactoryRun(runId, options?.signal),
|
|
317
|
-
listRuns: async () =>
|
|
327
|
+
listRuns: (async (options) => {
|
|
328
|
+
const page = await this.rpc.factory.listRuns(options ?? {});
|
|
329
|
+
return options === void 0 ? page.runs : page;
|
|
330
|
+
}),
|
|
318
331
|
getRunDetail: (runId) => this.rpc.factory.getRunDetail({ runId }),
|
|
319
332
|
getRunProgress: (runId, options = {}) => this.rpc.factory.getRunProgress({ runId, ...options }),
|
|
320
333
|
cancel: async (runId) => this.rpc.factory.cancel({ runId })
|
|
@@ -475,7 +488,7 @@ class CopilotSession {
|
|
|
475
488
|
const unsubscribe = this.on((event) => {
|
|
476
489
|
if (event.type === "assistant.message") {
|
|
477
490
|
lastAssistantMessage = event;
|
|
478
|
-
} else if (event.type === "session.idle") {
|
|
491
|
+
} else if (event.type === "session.idle" && event.data.mode !== "autopilot") {
|
|
479
492
|
resolveOutcome({ kind: "idle" });
|
|
480
493
|
} else if (event.type === "session.error") {
|
|
481
494
|
const error = new Error(event.data.message);
|
|
@@ -510,7 +523,15 @@ class CopilotSession {
|
|
|
510
523
|
}
|
|
511
524
|
/** @internal */
|
|
512
525
|
_markDisconnected() {
|
|
526
|
+
if (this.disconnected) {
|
|
527
|
+
return;
|
|
528
|
+
}
|
|
513
529
|
this.disconnected = true;
|
|
530
|
+
for (const controller of this.pendingExternalTools.values()) {
|
|
531
|
+
controller.abort();
|
|
532
|
+
}
|
|
533
|
+
this.pendingExternalTools.clear();
|
|
534
|
+
this._runOnDisconnected();
|
|
514
535
|
this.eventHandlers.clear();
|
|
515
536
|
this.typedEventHandlers.clear();
|
|
516
537
|
this.toolHandlers.clear();
|
|
@@ -530,6 +551,15 @@ class CopilotSession {
|
|
|
530
551
|
this.factoryAbortControllers.clear();
|
|
531
552
|
this.transformCallbacks?.clear();
|
|
532
553
|
}
|
|
554
|
+
/** @internal */
|
|
555
|
+
_runOnDisconnected() {
|
|
556
|
+
this.onDisconnected?.();
|
|
557
|
+
this.onDisconnected = void 0;
|
|
558
|
+
}
|
|
559
|
+
/** @internal */
|
|
560
|
+
_setOnDisconnected(callback) {
|
|
561
|
+
this.onDisconnected = callback;
|
|
562
|
+
}
|
|
533
563
|
on(eventTypeOrHandler, handler) {
|
|
534
564
|
if (typeof eventTypeOrHandler === "string" && handler) {
|
|
535
565
|
const eventType = eventTypeOrHandler;
|
|
@@ -604,6 +634,15 @@ class CopilotSession {
|
|
|
604
634
|
tracestate
|
|
605
635
|
);
|
|
606
636
|
}
|
|
637
|
+
} else if (event.type === "external_tool.completed") {
|
|
638
|
+
const { requestId } = event.data;
|
|
639
|
+
if (requestId) {
|
|
640
|
+
const controller = this.pendingExternalTools.get(requestId);
|
|
641
|
+
if (controller) {
|
|
642
|
+
this.pendingExternalTools.delete(requestId);
|
|
643
|
+
controller.abort();
|
|
644
|
+
}
|
|
645
|
+
}
|
|
607
646
|
} else if (event.type === "permission.requested") {
|
|
608
647
|
const { requestId, permissionRequest, resolvedByHook } = event.data;
|
|
609
648
|
if (resolvedByHook) {
|
|
@@ -684,16 +723,35 @@ class CopilotSession {
|
|
|
684
723
|
* @internal
|
|
685
724
|
*/
|
|
686
725
|
async _executeToolAndRespond(requestId, toolName, toolCallId, args, handler, traceparent, tracestate) {
|
|
726
|
+
const controller = new AbortController();
|
|
727
|
+
if (this.disconnected || this.pendingExternalTools.has(requestId)) {
|
|
728
|
+
return;
|
|
729
|
+
}
|
|
730
|
+
this.pendingExternalTools.set(requestId, controller);
|
|
687
731
|
try {
|
|
688
732
|
let availableTools;
|
|
689
733
|
if (toolName === TOOL_SEARCH_TOOL_NAME) {
|
|
734
|
+
if (controller.signal.aborted) {
|
|
735
|
+
return;
|
|
736
|
+
}
|
|
737
|
+
const aborted = new Promise((resolve) => {
|
|
738
|
+
controller.signal.addEventListener("abort", () => resolve(void 0), {
|
|
739
|
+
once: true
|
|
740
|
+
});
|
|
741
|
+
});
|
|
690
742
|
try {
|
|
691
|
-
const metadata = await
|
|
692
|
-
|
|
743
|
+
const metadata = await Promise.race([
|
|
744
|
+
this.rpc.tools.getCurrentMetadata(),
|
|
745
|
+
aborted
|
|
746
|
+
]);
|
|
747
|
+
availableTools = metadata?.tools ?? void 0;
|
|
693
748
|
} catch {
|
|
694
749
|
availableTools = void 0;
|
|
695
750
|
}
|
|
696
751
|
}
|
|
752
|
+
if (controller.signal.aborted) {
|
|
753
|
+
return;
|
|
754
|
+
}
|
|
697
755
|
const rawResult = await handler(args, {
|
|
698
756
|
sessionId: this.sessionId,
|
|
699
757
|
toolCallId,
|
|
@@ -701,7 +759,8 @@ class CopilotSession {
|
|
|
701
759
|
arguments: args,
|
|
702
760
|
availableTools,
|
|
703
761
|
traceparent,
|
|
704
|
-
tracestate
|
|
762
|
+
tracestate,
|
|
763
|
+
signal: controller.signal
|
|
705
764
|
});
|
|
706
765
|
let result;
|
|
707
766
|
if (rawResult == null) {
|
|
@@ -713,12 +772,12 @@ class CopilotSession {
|
|
|
713
772
|
} else {
|
|
714
773
|
result = JSON.stringify(rawResult);
|
|
715
774
|
}
|
|
716
|
-
if (this.
|
|
775
|
+
if (!this._claimExternalTool(requestId, controller)) {
|
|
717
776
|
return;
|
|
718
777
|
}
|
|
719
778
|
await this.rpc.tools.handlePendingToolCall({ requestId, result });
|
|
720
779
|
} catch (error) {
|
|
721
|
-
if (this.
|
|
780
|
+
if (!this._claimExternalTool(requestId, controller)) {
|
|
722
781
|
return;
|
|
723
782
|
}
|
|
724
783
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -729,7 +788,19 @@ class CopilotSession {
|
|
|
729
788
|
throw rpcError;
|
|
730
789
|
}
|
|
731
790
|
}
|
|
791
|
+
} finally {
|
|
792
|
+
if (this.pendingExternalTools.get(requestId) === controller) {
|
|
793
|
+
this.pendingExternalTools.delete(requestId);
|
|
794
|
+
}
|
|
795
|
+
controller.abort();
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
_claimExternalTool(requestId, controller) {
|
|
799
|
+
if (this.disconnected || this.pendingExternalTools.get(requestId) !== controller) {
|
|
800
|
+
return false;
|
|
732
801
|
}
|
|
802
|
+
this.pendingExternalTools.delete(requestId);
|
|
803
|
+
return true;
|
|
733
804
|
}
|
|
734
805
|
/**
|
|
735
806
|
* Executes a permission handler and sends the result back via RPC.
|
|
@@ -1174,7 +1245,13 @@ class CopilotSession {
|
|
|
1174
1245
|
}
|
|
1175
1246
|
try {
|
|
1176
1247
|
const result = await this.elicitationHandler(context);
|
|
1177
|
-
await this.rpc.ui.handlePendingElicitation({
|
|
1248
|
+
await this.rpc.ui.handlePendingElicitation({
|
|
1249
|
+
requestId,
|
|
1250
|
+
result: {
|
|
1251
|
+
action: result.action,
|
|
1252
|
+
...result.content ? { content: result.content } : {}
|
|
1253
|
+
}
|
|
1254
|
+
});
|
|
1178
1255
|
} catch {
|
|
1179
1256
|
try {
|
|
1180
1257
|
await this.rpc.ui.handlePendingElicitation({
|
|
@@ -1477,13 +1554,27 @@ class CopilotSession {
|
|
|
1477
1554
|
* ```
|
|
1478
1555
|
*/
|
|
1479
1556
|
async disconnect() {
|
|
1480
|
-
if (this.disconnected) {
|
|
1557
|
+
if (this.disconnected || this.disconnecting) {
|
|
1481
1558
|
return;
|
|
1482
1559
|
}
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1560
|
+
this.disconnecting = true;
|
|
1561
|
+
try {
|
|
1562
|
+
let response = { success: false };
|
|
1563
|
+
for (let attempt = 0; attempt < 2 && !response.success; attempt++) {
|
|
1564
|
+
response = await this.connection.sendRequest("session.detach", {
|
|
1565
|
+
sessionId: this.sessionId
|
|
1566
|
+
});
|
|
1567
|
+
}
|
|
1568
|
+
if (!response.success) {
|
|
1569
|
+
throw new Error(
|
|
1570
|
+
`Failed to disconnect session ${this.sessionId}: ${response.error || "Unknown error"}`
|
|
1571
|
+
);
|
|
1572
|
+
}
|
|
1573
|
+
this._markDisconnected();
|
|
1574
|
+
} catch (error) {
|
|
1575
|
+
this.disconnecting = false;
|
|
1576
|
+
throw error;
|
|
1577
|
+
}
|
|
1487
1578
|
}
|
|
1488
1579
|
/** Enables `await using session = ...` syntax for automatic cleanup. */
|
|
1489
1580
|
async [Symbol.asyncDispose]() {
|
|
@@ -1525,11 +1616,48 @@ class CopilotSession {
|
|
|
1525
1616
|
* ```typescript
|
|
1526
1617
|
* await session.setModel("gpt-5.4");
|
|
1527
1618
|
* await session.setModel("claude-sonnet-4.6", { reasoningEffort: "high" });
|
|
1619
|
+
*
|
|
1620
|
+
* // Select the Auto model and its routing preference in one call.
|
|
1621
|
+
* await session.setModel("auto", { autoTier: "intelligence" });
|
|
1528
1622
|
* ```
|
|
1529
1623
|
*/
|
|
1530
1624
|
async setModel(model, options) {
|
|
1531
1625
|
await this.rpc.model.switchTo({ modelId: model, ...options });
|
|
1532
1626
|
}
|
|
1627
|
+
/**
|
|
1628
|
+
* Change the Auto routing preference without changing the selected model.
|
|
1629
|
+
*
|
|
1630
|
+
* The runtime does not apply the preference immediately. It records the
|
|
1631
|
+
* request and commits it only when a later user turn using the `auto` model
|
|
1632
|
+
* successfully obtains a usable model from the provider. A `pending` status
|
|
1633
|
+
* therefore confirms that the request was accepted, not that it took effect.
|
|
1634
|
+
*
|
|
1635
|
+
* Watch for the outcome through the `session.model_change` event on success,
|
|
1636
|
+
* or the ephemeral `session.auto_tier_switch_failed` event on failure. You
|
|
1637
|
+
* can also read the current committed and in-flight state at any time with
|
|
1638
|
+
* `session.rpc.model.getCurrent()`.
|
|
1639
|
+
*
|
|
1640
|
+
* Only the most recent request survives: issuing a new request replaces any
|
|
1641
|
+
* earlier one that has not yet been claimed by a turn.
|
|
1642
|
+
*
|
|
1643
|
+
* @param autoTier - Routing preference to activate, or `null` to return to
|
|
1644
|
+
* the provider's default Auto routing
|
|
1645
|
+
* @returns The runtime's immediate acknowledgement and Auto preference snapshot
|
|
1646
|
+
*
|
|
1647
|
+
* @experimental Part of an experimental Auto routing surface and may change
|
|
1648
|
+
* or be removed in a future release.
|
|
1649
|
+
*
|
|
1650
|
+
* @example
|
|
1651
|
+
* ```typescript
|
|
1652
|
+
* const result = await session.setAutoTier("intelligence");
|
|
1653
|
+
* if (result.status === "pending") {
|
|
1654
|
+
* // Takes effect on a later turn that uses the `auto` model.
|
|
1655
|
+
* }
|
|
1656
|
+
* ```
|
|
1657
|
+
*/
|
|
1658
|
+
async setAutoTier(autoTier) {
|
|
1659
|
+
return await this.rpc.model.switchAutoTier({ autoTier });
|
|
1660
|
+
}
|
|
1533
1661
|
/**
|
|
1534
1662
|
* Log a message to the session timeline.
|
|
1535
1663
|
* The message appears in the session event stream and is visible to SDK consumers
|
|
@@ -22,6 +22,7 @@ __export(types_exports, {
|
|
|
22
22
|
CopilotWebSocketCloseStatus: () => import_copilotRequestHandler.CopilotWebSocketCloseStatus,
|
|
23
23
|
CopilotWebSocketForwarder: () => import_copilotRequestHandler.CopilotWebSocketForwarder,
|
|
24
24
|
CopilotWebSocketHandler: () => import_copilotRequestHandler.CopilotWebSocketHandler,
|
|
25
|
+
DisableBypassPermissionsModes: () => DisableBypassPermissionsModes,
|
|
25
26
|
RuntimeConnection: () => RuntimeConnection,
|
|
26
27
|
SYSTEM_MESSAGE_SECTIONS: () => SYSTEM_MESSAGE_SECTIONS,
|
|
27
28
|
SessionFsSqliteTransactionFailure: () => import_sessionFsProvider2.SessionFsSqliteTransactionFailure,
|
|
@@ -165,12 +166,19 @@ const approveAll = (request, invocation) => {
|
|
|
165
166
|
const defaultJoinSessionPermissionHandler = () => ({
|
|
166
167
|
kind: "no-result"
|
|
167
168
|
});
|
|
169
|
+
const DisableBypassPermissionsModes = {
|
|
170
|
+
/** Turn off bypass-permissions mode entirely. */
|
|
171
|
+
Disable: "disable",
|
|
172
|
+
/** Permit automatic bypass but block full allow-all. */
|
|
173
|
+
AllowAutoOnly: "allow-auto-only"
|
|
174
|
+
};
|
|
168
175
|
// Annotate the CommonJS export names for ESM import in node:
|
|
169
176
|
0 && (module.exports = {
|
|
170
177
|
CopilotRequestHandler,
|
|
171
178
|
CopilotWebSocketCloseStatus,
|
|
172
179
|
CopilotWebSocketForwarder,
|
|
173
180
|
CopilotWebSocketHandler,
|
|
181
|
+
DisableBypassPermissionsModes,
|
|
174
182
|
RuntimeConnection,
|
|
175
183
|
SYSTEM_MESSAGE_SECTIONS,
|
|
176
184
|
SessionFsSqliteTransactionFailure,
|