@github/copilot-sdk 1.0.13-preview.4 → 1.0.13

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/index.d.ts CHANGED
@@ -11,5 +11,5 @@ export { defineFactory, FactoryResumeError, isFactoryRunTerminal } from "./facto
11
11
  export { Canvas, CanvasError, createCanvas, type CanvasAction, type CanvasDeclaration, type CanvasHostContext, type CanvasHostContextCapabilities, type CanvasJsonSchema, type CanvasOptions, } from "./canvas.js";
12
12
  export { defineTool, approveAll, createAttributedPermissionResult, convertMcpCallToolResult, createSessionFsAdapter, CopilotRequestHandler, CopilotWebSocketHandler, CopilotWebSocketCloseStatus, CopilotWebSocketForwarder, SessionFsSqliteTransactionFailure, SYSTEM_MESSAGE_SECTIONS, } from "./types.js";
13
13
  export type * from "./generated/session-events.js";
14
- export type { AskUserVariant, CommandContext, CommandDefinition, CommandHandler, CanvasProviderIdentity, CloudSessionOptions, CloudSessionRepository, AutoModeSwitchHandler, AutoModeSwitchRequest, AutoModeSwitchResponse, AgentStopHandler, AgentStopHookInput, AgentStopHookOutput, UserPromptTransformedHandler, UserPromptTransformedHookInput, UserPromptTransformedHookOutput, CopilotClientMode, CopilotClientOptions, CopilotExpAssignmentResponse, StdioRuntimeConnection, InProcessRuntimeConnection, TcpRuntimeConnection, UriRuntimeConnection, ChildProcessRuntimeConnection, CustomAgentConfig, ElicitationFieldValue, ElicitationHandler, ElicitationParams, ElicitationContext, ElicitationResult, ElicitationSchema, ElicitationSchemaField, ExpConfigEntry, ExpFlagValue, ExitPlanModeHandler, ExitPlanModeRequest, ExitPlanModeResult, ExtensionInfo, ForegroundSessionInfo, GetAuthStatusResponse, GetStatusResponse, GitHubMcpToolConfig, GitHubTelemetryNotification, GitHubTelemetryEvent, GitHubTelemetryClientInfo, GitHubTokenAcquireReason, GitHubTokenAcquireResult, GitHubTokenProvider, GitHubTokenProviderArgs, GitHubTokenProviderResult, InfiniteSessionConfig, LargeToolOutputConfig, MemoryConfiguration, UiInputOptions, FactoryLimits, FactoryMeta, MCPStdioServerConfig, MCPHTTPServerConfig, MCPServerConfig, DefaultAgentConfig, BearerTokenProvider, MessageOptions, ManagedSettings, ManagedSettingsPermissions, ModelBilling, ModelBillingTokenPrices, ModelBillingTokenPricesLongContext, CapiSessionOptions, ModelCapabilities, ModelCapabilitiesOverride, ModelInfo, ModelPolicy, NamedProviderConfig, PermissionHandler, PermissionRequest, PermissionRequestedData, PermissionRequestedEvent, PermissionRequestResult, AttributedPermissionResult, PermissionDecisionContext, PermissionDecisionOutcome, PermissionDecisionSource, PermissionDecisionSurface, PermissionResponseCapability, ProviderConfig, ProviderModelConfig, ProviderTokenArgs, RemoteSessionMode, ResumeSessionConfig, SectionOverride, SectionOverrideAction, SectionTransformFn, SessionCapabilities, SessionConfig, SessionConfigBase, SessionEvent, SessionEventHandler, SessionEventPayload, SessionEventType, SessionLifecycleEvent, SessionLifecycleEventMetadata, SessionLifecycleEventType, SessionLifecycleHandler, SessionHooks, SessionCreatedEvent, SessionDeletedEvent, SessionUpdatedEvent, SessionForegroundEvent, SessionBackgroundEvent, SessionContext, SessionListFilter, SessionMetadata, SessionUiApi, SessionFsConfig, SessionFsProvider, SessionFsFileInfo, SessionFsSqliteQueryResult, SessionFsSqliteQueryType, SessionFsSqliteProvider, SessionFsSqliteStatement, SessionFsSqliteTransactionErrorClass, CopilotRequestContext, SystemMessageAppendConfig, SystemMessageConfig, SystemMessageCustomizeConfig, SystemMessageReplaceConfig, SystemMessageSection, TelemetryConfig, TraceContext, TraceContextProvider, Tool, ToolHandler, ToolInvocation, CurrentToolMetadata, ToolTelemetry, ToolResultObject, ToolSearchConfig, TypedSessionEventHandler, TypedSessionLifecycleHandler, ZodSchema, } from "./types.js";
14
+ export type { AskUserVariant, CommandContext, CommandDefinition, CommandHandler, CanvasProviderIdentity, CloudSessionOptions, CloudSessionRepository, AutoModeSwitchHandler, AutoModeSwitchRequest, AutoModeSwitchResponse, AgentStopHandler, AgentStopHookInput, AgentStopHookOutput, UserPromptTransformedHandler, UserPromptTransformedHookInput, UserPromptTransformedHookOutput, CopilotClientInfo, CopilotClientMode, CopilotClientOptions, CopilotExpAssignmentResponse, StdioRuntimeConnection, InProcessRuntimeConnection, TcpRuntimeConnection, UriRuntimeConnection, ChildProcessRuntimeConnection, CustomAgentConfig, ElicitationFieldValue, ElicitationHandler, ElicitationParams, ElicitationContext, ElicitationResult, ElicitationSchema, ElicitationSchemaField, ExpConfigEntry, ExpFlagValue, ExitPlanModeHandler, ExitPlanModeRequest, ExitPlanModeResult, ExtensionInfo, ForegroundSessionInfo, GetAuthStatusResponse, GetStatusResponse, GitHubMcpToolConfig, GitHubTelemetryNotification, GitHubTelemetryEvent, GitHubTelemetryClientInfo, GitHubTokenAcquireReason, GitHubTokenAcquireResult, GitHubTokenProvider, GitHubTokenProviderArgs, GitHubTokenProviderResult, InfiniteSessionConfig, LargeToolOutputConfig, MemoryConfiguration, UiInputOptions, FactoryLimits, FactoryMeta, MCPStdioServerConfig, MCPHTTPServerConfig, MCPServerConfig, DefaultAgentConfig, BearerTokenProvider, MessageOptions, ManagedSettings, ManagedSettingsPermissions, ModelBilling, ModelBillingTokenPrices, ModelBillingTokenPricesLongContext, AutoTier, CapiSessionOptions, CurrentModel, ModelSwitchAutoTierResult, ModelSwitchAutoTierStatus, ModelCapabilities, ModelCapabilitiesOverride, ModelInfo, ModelPolicy, NamedProviderConfig, PermissionHandler, PermissionRequest, PermissionRequestedData, PermissionRequestedEvent, PermissionRequestResult, AttributedPermissionResult, PermissionDecisionContext, PermissionDecisionOutcome, PermissionDecisionSource, PermissionDecisionSurface, PermissionResponseCapability, ProviderConfig, ProviderModelConfig, ProviderTokenArgs, RemoteSessionMode, ResumeSessionConfig, SectionOverride, SectionOverrideAction, SectionTransformFn, SessionCapabilities, SessionConfig, SessionConfigBase, SessionEvent, SessionEventHandler, SessionEventPayload, SessionEventType, SessionLifecycleEvent, SessionLifecycleEventMetadata, SessionLifecycleEventType, SessionLifecycleHandler, SessionHooks, SessionCreatedEvent, SessionDeletedEvent, SessionUpdatedEvent, SessionForegroundEvent, SessionBackgroundEvent, SessionContext, SessionListFilter, SessionMetadata, SessionUiApi, SessionFsConfig, SessionFsProvider, SessionFsFileInfo, SessionFsSqliteQueryResult, SessionFsSqliteQueryType, SessionFsSqliteProvider, SessionFsSqliteStatement, SessionFsSqliteTransactionErrorClass, CopilotRequestContext, SystemMessageAppendConfig, SystemMessageConfig, SystemMessageCustomizeConfig, SystemMessageReplaceConfig, SystemMessageSection, TelemetryConfig, TraceContext, TraceContextProvider, Tool, ToolHandler, ToolInvocation, CurrentToolMetadata, ToolTelemetry, ToolResultObject, ToolSearchConfig, TypedSessionEventHandler, TypedSessionLifecycleHandler, ZodSchema, } from "./types.js";
15
15
  export type { RunOptions, ResumeOptions, FactoryResumeErrorCode, SessionFactoryApi, FactoryAgentOptions, FactoryContext, FactoryDefinition, FactoryHandle, FactoryJsonSchema, JsonValue, FactoryPipelineStage, FactoryStepOptions, FactoryRunResult, FactoryRunStatus, FactoryRunSummary, FactoryListRunsOptions, FactoryRunsPage, FactoryRunDetail, FactoryProgressPage, FactoryProgressLine, FactoryPhaseObservation, FactoryPhaseStatus, FactoryAgentSummary, } from "./factory.js";
@@ -2,5 +2,17 @@ export interface RuntimeArtifactSources {
2
2
  packageRoot: string;
3
3
  platform: string;
4
4
  }
5
+ export interface EnsureRuntimeBundleOptions {
6
+ cacheRoot?: string;
7
+ packageSearchPaths?: string[];
8
+ platform?: string;
9
+ }
10
+ export declare const RUNTIME_PLATFORMS: readonly ["darwin-arm64", "darwin-x64", "linux-arm64", "linux-x64", "linuxmusl-arm64", "linuxmusl-x64", "win32-arm64", "win32-x64"];
11
+ export declare function validateFile(path: string, label: string): void;
5
12
  export declare function defaultRuntimeCacheRoot(platform?: NodeJS.Platform, home?: string, environment?: NodeJS.ProcessEnv): string;
6
- export declare function materializeRuntimeBundle(sources: RuntimeArtifactSources, cacheRoot?: string): string;
13
+ export declare function materializeRuntimeBundle(sources: RuntimeArtifactSources, cacheRoot?: string, cacheKey?: string): string;
14
+ export declare function getRuntimePlatform(platform?: NodeJS.Platform, arch?: NodeJS.Architecture, musl?: boolean): string;
15
+ export declare function getRuntimeReleaseAssetName(version: string, platform: string): string;
16
+ export declare function getRuntimePackageName(platform: string): string;
17
+ export declare function resolvePackageRoot(packageName: string, searchPaths?: string[]): string | undefined;
18
+ export declare function ensureRuntimeBundle(version: string, options?: EnsureRuntimeBundleOptions): Promise<string>;
@@ -1,4 +1,3 @@
1
- import { createHash } from "node:crypto";
2
1
  import {
3
2
  chmodSync,
4
3
  copyFileSync,
@@ -11,26 +10,37 @@ import {
11
10
  rmSync,
12
11
  statSync
13
12
  } from "node:fs";
13
+ import { createHash } from "node:crypto";
14
+ import { createRequire } from "node:module";
14
15
  import { homedir } from "node:os";
15
16
  import { dirname, join, relative, sep } from "node:path";
17
+ import { COPILOT_CLI_USE_NPM_PACKAGE } from "./cliVersion.js";
18
+ const require2 = createRequire(typeof __filename === "string" ? __filename : import.meta.url);
19
+ const RUNTIME_PLATFORMS = [
20
+ "darwin-arm64",
21
+ "darwin-x64",
22
+ "linux-arm64",
23
+ "linux-x64",
24
+ "linuxmusl-arm64",
25
+ "linuxmusl-x64",
26
+ "win32-arm64",
27
+ "win32-x64"
28
+ ];
16
29
  const EXCLUDED_TOP_LEVEL = /* @__PURE__ */ new Set([
17
30
  "app.js",
18
31
  "assets",
19
32
  "changelog.json",
20
33
  "copilot",
21
34
  "copilot.exe",
22
- "copilot-sdk",
23
35
  "foundry-local-sdk",
24
36
  "index.js",
25
37
  "LICENSE.md",
26
38
  "napi-oop-runtime",
27
39
  "npm-loader.js",
28
40
  "package.json",
29
- "preloads",
30
41
  "pvrecorder",
31
42
  "queries",
32
43
  "README.md",
33
- "sdk",
34
44
  "sea-loader.js",
35
45
  "webview"
36
46
  ]);
@@ -69,14 +79,12 @@ function collectRuntimeAssets(sources) {
69
79
  continue;
70
80
  }
71
81
  const parts = sourceRelative.split(sep);
72
- let relativePath = sourceRelative;
73
82
  if (parts[0] === "prebuilds") {
74
83
  if (parts[1] !== sources.platform || parts.length < 3) {
75
84
  continue;
76
85
  }
77
- relativePath = parts.slice(2).join(sep);
78
86
  }
79
- assets.push({ source, relativePath });
87
+ assets.push({ source, relativePath: sourceRelative });
80
88
  }
81
89
  };
82
90
  visit(sources.packageRoot);
@@ -104,15 +112,20 @@ function defaultRuntimeCacheRoot(platform = process.platform, home = homedir(),
104
112
  const cacheDirectory = platform === "win32" ? environment.LOCALAPPDATA ?? join(home, "AppData", "Local") : platform === "darwin" ? join(home, "Library", "Caches") : environment.XDG_CACHE_HOME ?? join(home, ".cache");
105
113
  return join(cacheDirectory, "github-copilot-sdk", "runtime");
106
114
  }
107
- function materializeRuntimeBundle(sources, cacheRoot = defaultRuntimeCacheRoot()) {
115
+ function materializeRuntimeBundle(sources, cacheRoot = defaultRuntimeCacheRoot(), cacheKey = `${sources.platform}-${sourceFingerprint(collectRuntimeAssets(sources))}`) {
108
116
  const assets = collectRuntimeAssets(sources);
109
- const wrapperName = process.platform === "win32" ? "copilot-runtime.exe" : "copilot-runtime";
110
- const sourceWrapper = assets.find((asset) => asset.relativePath === wrapperName)?.source;
111
- const sourceRuntimeNode = assets.find((asset) => asset.relativePath === "runtime.node")?.source;
117
+ const wrapperName = sources.platform.startsWith("win32") ? "copilot-runtime.exe" : "copilot-runtime";
118
+ const prebuildDir = join("prebuilds", sources.platform);
119
+ const wrapperRelative = join(prebuildDir, wrapperName);
120
+ const runtimeNodeRelative = join(prebuildDir, "runtime.node");
121
+ const sourceWrapper = assets.find((asset) => asset.relativePath === wrapperRelative)?.source;
122
+ const sourceRuntimeNode = assets.find(
123
+ (asset) => asset.relativePath === runtimeNodeRelative
124
+ )?.source;
112
125
  validateRuntimeBundle(sourceWrapper ?? "", sourceRuntimeNode ?? "");
113
- const installDir = join(cacheRoot, `${sources.platform}-${sourceFingerprint(assets)}`);
114
- const installedWrapper = join(installDir, wrapperName);
115
- const installedRuntimeNode = join(installDir, "runtime.node");
126
+ const installDir = join(cacheRoot, cacheKey);
127
+ const installedWrapper = join(installDir, wrapperRelative);
128
+ const installedRuntimeNode = join(installDir, runtimeNodeRelative);
116
129
  if (existsSync(installDir)) {
117
130
  validateRuntimeBundle(installedWrapper, installedRuntimeNode);
118
131
  makeExecutable(installedWrapper);
@@ -126,7 +139,7 @@ function materializeRuntimeBundle(sources, cacheRoot = defaultRuntimeCacheRoot()
126
139
  mkdirSync(dirname(destination), { recursive: true });
127
140
  copyFileSync(asset.source, destination);
128
141
  }
129
- const stagedWrapper = join(stagingDir, wrapperName);
142
+ const stagedWrapper = join(stagingDir, wrapperRelative);
130
143
  makeExecutable(stagedWrapper);
131
144
  renameSync(stagingDir, installDir);
132
145
  } catch (error) {
@@ -139,7 +152,81 @@ function materializeRuntimeBundle(sources, cacheRoot = defaultRuntimeCacheRoot()
139
152
  }
140
153
  return installedWrapper;
141
154
  }
155
+ function isMusl() {
156
+ if (process.platform !== "linux") {
157
+ return false;
158
+ }
159
+ const report = process.report?.getReport();
160
+ return report?.header?.glibcVersionRuntime === void 0;
161
+ }
162
+ function getRuntimePlatform(platform = process.platform, arch = process.arch, musl = isMusl()) {
163
+ if (arch !== "x64" && arch !== "arm64") {
164
+ throw new Error(`Unsupported Copilot CLI architecture: ${arch}.`);
165
+ }
166
+ if (platform === "linux") {
167
+ return `${musl ? "linuxmusl" : "linux"}-${arch}`;
168
+ }
169
+ if (platform === "darwin" || platform === "win32") {
170
+ return `${platform}-${arch}`;
171
+ }
172
+ throw new Error(`Unsupported Copilot CLI platform: ${platform}-${arch}.`);
173
+ }
174
+ function getRuntimeReleaseAssetName(version, platform) {
175
+ return `github-copilot-${version}-${platform}.tgz`;
176
+ }
177
+ function getRuntimePackageName(platform) {
178
+ return `@github/copilot-sdk-${platform}`;
179
+ }
180
+ function resolvePackageRoot(packageName, searchPaths = require2.resolve.paths(packageName) ?? []) {
181
+ return searchPaths.map((base) => join(base, ...packageName.split("/"))).find((candidate) => existsSync(join(candidate, "package.json")));
182
+ }
183
+ async function ensureRuntimeBundle(version, options = {}) {
184
+ const platform = options.platform ?? getRuntimePlatform();
185
+ if (COPILOT_CLI_USE_NPM_PACKAGE) {
186
+ const packageName2 = `@github/copilot-${platform}`;
187
+ const packageRoot2 = resolvePackageRoot(packageName2, options.packageSearchPaths);
188
+ if (!packageRoot2) {
189
+ throw new Error(`Could not resolve ${packageName2} for Copilot CLI ${version}.`);
190
+ }
191
+ validateFile(
192
+ join(packageRoot2, "prebuilds", platform, "runtime.node"),
193
+ "Copilot runtime.node"
194
+ );
195
+ return materializeRuntimeBundle(
196
+ { packageRoot: packageRoot2, platform },
197
+ options.cacheRoot,
198
+ `${version}-${platform}`
199
+ );
200
+ }
201
+ const packageName = getRuntimePackageName(platform);
202
+ const packageRoot = resolvePackageRoot(packageName, options.packageSearchPaths);
203
+ if (!packageRoot) {
204
+ throw new Error(
205
+ `Could not resolve ${packageName}. Reinstall @github/copilot-sdk so its platform package is installed.`
206
+ );
207
+ }
208
+ const wrapperName = platform.startsWith("win32") ? "copilot-runtime.exe" : "copilot-runtime";
209
+ const prebuildDir = join(packageRoot, "prebuilds", platform);
210
+ const wrapper = join(prebuildDir, wrapperName);
211
+ try {
212
+ validateRuntimeBundle(wrapper, join(prebuildDir, "runtime.node"));
213
+ } catch (error) {
214
+ throw new Error(
215
+ `${packageName} is missing required Copilot CLI runtime files. Reinstall @github/copilot-sdk.`,
216
+ { cause: error }
217
+ );
218
+ }
219
+ makeExecutable(wrapper);
220
+ return wrapper;
221
+ }
142
222
  export {
223
+ RUNTIME_PLATFORMS,
143
224
  defaultRuntimeCacheRoot,
144
- materializeRuntimeBundle
225
+ ensureRuntimeBundle,
226
+ getRuntimePackageName,
227
+ getRuntimePlatform,
228
+ getRuntimeReleaseAssetName,
229
+ materializeRuntimeBundle,
230
+ resolvePackageRoot,
231
+ validateFile
145
232
  };
package/dist/session.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { createSessionRpc } from "./generated/rpc.js";
2
+ import type { ModelSwitchAutoTierResult } from "./generated/rpc.js";
2
3
  import type { OpenCanvasInstance } from "./generated/rpc.js";
3
- import type { MessageOptions, ContextTier, ReasoningEffort, ReasoningSummary, ModelCapabilitiesOverride, SessionCapabilities, SessionEvent, SessionEventHandler, SessionEventType, SessionUiApi, TypedSessionEventHandler } from "./types.js";
4
+ import type { MessageOptions, ContextTier, ReasoningEffort, ReasoningSummary, AutoTier, ModelCapabilitiesOverride, SessionCapabilities, SessionEvent, SessionEventHandler, SessionEventType, SessionUiApi, TypedSessionEventHandler } from "./types.js";
4
5
  import { type SessionFactoryApi } from "./factory.js";
5
6
  /** Assistant message event - the final response from the assistant. */
6
7
  export type AssistantMessageEvent = Extract<SessionEvent, {
@@ -43,6 +44,7 @@ export declare class CopilotSession {
43
44
  private eventHandlers;
44
45
  private typedEventHandlers;
45
46
  private toolHandlers;
47
+ private pendingExternalTools;
46
48
  private canvases;
47
49
  private bearerTokenProviders;
48
50
  private commandHandlers;
@@ -62,6 +64,7 @@ export declare class CopilotSession {
62
64
  private _capabilities;
63
65
  private openCanvasInstances;
64
66
  private disconnected;
67
+ private disconnecting;
65
68
  private onDisconnected?;
66
69
  /**
67
70
  * Friendly factory API for running registered factories by name or handle.
@@ -212,6 +215,7 @@ export declare class CopilotSession {
212
215
  private removeOpenCanvasFromEvent;
213
216
  private removeOpenCanvas;
214
217
  private upsertOpenCanvas;
218
+ private _claimExternalTool;
215
219
  /**
216
220
  * Snapshot of canvas instances currently known to be open for this session.
217
221
  * Populated from the `session.resume` response and live `session.canvas.opened`
@@ -300,6 +304,9 @@ export declare class CopilotSession {
300
304
  * ```typescript
301
305
  * await session.setModel("gpt-5.4");
302
306
  * await session.setModel("claude-sonnet-4.6", { reasoningEffort: "high" });
307
+ *
308
+ * // Select the Auto model and its routing preference in one call.
309
+ * await session.setModel("auto", { autoTier: "intelligence" });
303
310
  * ```
304
311
  */
305
312
  setModel(model: string, options?: {
@@ -307,7 +314,51 @@ export declare class CopilotSession {
307
314
  reasoningSummary?: ReasoningSummary;
308
315
  contextTier?: ContextTier;
309
316
  modelCapabilities?: ModelCapabilitiesOverride;
317
+ /**
318
+ * Routing preference to apply when `model` is `auto`.
319
+ *
320
+ * Pass `null` to return to the provider's default Auto routing. The
321
+ * runtime rejects this option when `model` is anything other than
322
+ * `auto`; use {@link setAutoTier} to change the preference without
323
+ * changing the selected model.
324
+ *
325
+ * @experimental Part of an experimental Auto routing surface and may
326
+ * change or be removed in a future release.
327
+ */
328
+ autoTier?: AutoTier | null;
310
329
  }): Promise<void>;
330
+ /**
331
+ * Change the Auto routing preference without changing the selected model.
332
+ *
333
+ * The runtime does not apply the preference immediately. It records the
334
+ * request and commits it only when a later user turn using the `auto` model
335
+ * successfully obtains a usable model from the provider. A `pending` status
336
+ * therefore confirms that the request was accepted, not that it took effect.
337
+ *
338
+ * Watch for the outcome through the `session.model_change` event on success,
339
+ * or the ephemeral `session.auto_tier_switch_failed` event on failure. You
340
+ * can also read the current committed and in-flight state at any time with
341
+ * `session.rpc.model.getCurrent()`.
342
+ *
343
+ * Only the most recent request survives: issuing a new request replaces any
344
+ * earlier one that has not yet been claimed by a turn.
345
+ *
346
+ * @param autoTier - Routing preference to activate, or `null` to return to
347
+ * the provider's default Auto routing
348
+ * @returns The runtime's immediate acknowledgement and Auto preference snapshot
349
+ *
350
+ * @experimental Part of an experimental Auto routing surface and may change
351
+ * or be removed in a future release.
352
+ *
353
+ * @example
354
+ * ```typescript
355
+ * const result = await session.setAutoTier("intelligence");
356
+ * if (result.status === "pending") {
357
+ * // Takes effect on a later turn that uses the `auto` model.
358
+ * }
359
+ * ```
360
+ */
361
+ setAutoTier(autoTier: AutoTier | null): Promise<ModelSwitchAutoTierResult>;
311
362
  /**
312
363
  * Log a message to the session timeline.
313
364
  * The message appears in the session event stream and is visible to SDK consumers
package/dist/session.js CHANGED
@@ -231,6 +231,7 @@ class CopilotSession {
231
231
  eventHandlers = /* @__PURE__ */ new Set();
232
232
  typedEventHandlers = /* @__PURE__ */ new Map();
233
233
  toolHandlers = /* @__PURE__ */ new Map();
234
+ pendingExternalTools = /* @__PURE__ */ new Map();
234
235
  canvases = /* @__PURE__ */ new Map();
235
236
  bearerTokenProviders = /* @__PURE__ */ new Map();
236
237
  commandHandlers = /* @__PURE__ */ new Map();
@@ -250,6 +251,7 @@ class CopilotSession {
250
251
  _capabilities = {};
251
252
  openCanvasInstances = [];
252
253
  disconnected = false;
254
+ disconnecting = false;
253
255
  onDisconnected;
254
256
  /** @internal Client session API handlers, populated by CopilotClient during create/resume. */
255
257
  clientSessionApis = {};
@@ -507,6 +509,10 @@ class CopilotSession {
507
509
  return;
508
510
  }
509
511
  this.disconnected = true;
512
+ for (const controller of this.pendingExternalTools.values()) {
513
+ controller.abort();
514
+ }
515
+ this.pendingExternalTools.clear();
510
516
  this._runOnDisconnected();
511
517
  this.eventHandlers.clear();
512
518
  this.typedEventHandlers.clear();
@@ -610,6 +616,15 @@ class CopilotSession {
610
616
  tracestate
611
617
  );
612
618
  }
619
+ } else if (event.type === "external_tool.completed") {
620
+ const { requestId } = event.data;
621
+ if (requestId) {
622
+ const controller = this.pendingExternalTools.get(requestId);
623
+ if (controller) {
624
+ this.pendingExternalTools.delete(requestId);
625
+ controller.abort();
626
+ }
627
+ }
613
628
  } else if (event.type === "permission.requested") {
614
629
  const { requestId, permissionRequest, resolvedByHook } = event.data;
615
630
  if (resolvedByHook) {
@@ -690,16 +705,35 @@ class CopilotSession {
690
705
  * @internal
691
706
  */
692
707
  async _executeToolAndRespond(requestId, toolName, toolCallId, args, handler, traceparent, tracestate) {
708
+ const controller = new AbortController();
709
+ if (this.disconnected || this.pendingExternalTools.has(requestId)) {
710
+ return;
711
+ }
712
+ this.pendingExternalTools.set(requestId, controller);
693
713
  try {
694
714
  let availableTools;
695
715
  if (toolName === TOOL_SEARCH_TOOL_NAME) {
716
+ if (controller.signal.aborted) {
717
+ return;
718
+ }
719
+ const aborted = new Promise((resolve) => {
720
+ controller.signal.addEventListener("abort", () => resolve(void 0), {
721
+ once: true
722
+ });
723
+ });
696
724
  try {
697
- const metadata = await this.rpc.tools.getCurrentMetadata();
698
- availableTools = metadata.tools ?? void 0;
725
+ const metadata = await Promise.race([
726
+ this.rpc.tools.getCurrentMetadata(),
727
+ aborted
728
+ ]);
729
+ availableTools = metadata?.tools ?? void 0;
699
730
  } catch {
700
731
  availableTools = void 0;
701
732
  }
702
733
  }
734
+ if (controller.signal.aborted) {
735
+ return;
736
+ }
703
737
  const rawResult = await handler(args, {
704
738
  sessionId: this.sessionId,
705
739
  toolCallId,
@@ -707,7 +741,8 @@ class CopilotSession {
707
741
  arguments: args,
708
742
  availableTools,
709
743
  traceparent,
710
- tracestate
744
+ tracestate,
745
+ signal: controller.signal
711
746
  });
712
747
  let result;
713
748
  if (rawResult == null) {
@@ -719,12 +754,12 @@ class CopilotSession {
719
754
  } else {
720
755
  result = JSON.stringify(rawResult);
721
756
  }
722
- if (this.disconnected) {
757
+ if (!this._claimExternalTool(requestId, controller)) {
723
758
  return;
724
759
  }
725
760
  await this.rpc.tools.handlePendingToolCall({ requestId, result });
726
761
  } catch (error) {
727
- if (this.disconnected) {
762
+ if (!this._claimExternalTool(requestId, controller)) {
728
763
  return;
729
764
  }
730
765
  const message = error instanceof Error ? error.message : String(error);
@@ -735,7 +770,19 @@ class CopilotSession {
735
770
  throw rpcError;
736
771
  }
737
772
  }
773
+ } finally {
774
+ if (this.pendingExternalTools.get(requestId) === controller) {
775
+ this.pendingExternalTools.delete(requestId);
776
+ }
777
+ controller.abort();
778
+ }
779
+ }
780
+ _claimExternalTool(requestId, controller) {
781
+ if (this.disconnected || this.pendingExternalTools.get(requestId) !== controller) {
782
+ return false;
738
783
  }
784
+ this.pendingExternalTools.delete(requestId);
785
+ return true;
739
786
  }
740
787
  /**
741
788
  * Executes a permission handler and sends the result back via RPC.
@@ -1489,13 +1536,27 @@ class CopilotSession {
1489
1536
  * ```
1490
1537
  */
1491
1538
  async disconnect() {
1492
- if (this.disconnected) {
1539
+ if (this.disconnected || this.disconnecting) {
1493
1540
  return;
1494
1541
  }
1495
- await this.connection.sendRequest("session.destroy", {
1496
- sessionId: this.sessionId
1497
- });
1498
- this._markDisconnected();
1542
+ this.disconnecting = true;
1543
+ try {
1544
+ let response = { success: false };
1545
+ for (let attempt = 0; attempt < 2 && !response.success; attempt++) {
1546
+ response = await this.connection.sendRequest("session.detach", {
1547
+ sessionId: this.sessionId
1548
+ });
1549
+ }
1550
+ if (!response.success) {
1551
+ throw new Error(
1552
+ `Failed to disconnect session ${this.sessionId}: ${response.error || "Unknown error"}`
1553
+ );
1554
+ }
1555
+ this._markDisconnected();
1556
+ } catch (error) {
1557
+ this.disconnecting = false;
1558
+ throw error;
1559
+ }
1499
1560
  }
1500
1561
  /** Enables `await using session = ...` syntax for automatic cleanup. */
1501
1562
  async [Symbol.asyncDispose]() {
@@ -1537,11 +1598,48 @@ class CopilotSession {
1537
1598
  * ```typescript
1538
1599
  * await session.setModel("gpt-5.4");
1539
1600
  * await session.setModel("claude-sonnet-4.6", { reasoningEffort: "high" });
1601
+ *
1602
+ * // Select the Auto model and its routing preference in one call.
1603
+ * await session.setModel("auto", { autoTier: "intelligence" });
1540
1604
  * ```
1541
1605
  */
1542
1606
  async setModel(model, options) {
1543
1607
  await this.rpc.model.switchTo({ modelId: model, ...options });
1544
1608
  }
1609
+ /**
1610
+ * Change the Auto routing preference without changing the selected model.
1611
+ *
1612
+ * The runtime does not apply the preference immediately. It records the
1613
+ * request and commits it only when a later user turn using the `auto` model
1614
+ * successfully obtains a usable model from the provider. A `pending` status
1615
+ * therefore confirms that the request was accepted, not that it took effect.
1616
+ *
1617
+ * Watch for the outcome through the `session.model_change` event on success,
1618
+ * or the ephemeral `session.auto_tier_switch_failed` event on failure. You
1619
+ * can also read the current committed and in-flight state at any time with
1620
+ * `session.rpc.model.getCurrent()`.
1621
+ *
1622
+ * Only the most recent request survives: issuing a new request replaces any
1623
+ * earlier one that has not yet been claimed by a turn.
1624
+ *
1625
+ * @param autoTier - Routing preference to activate, or `null` to return to
1626
+ * the provider's default Auto routing
1627
+ * @returns The runtime's immediate acknowledgement and Auto preference snapshot
1628
+ *
1629
+ * @experimental Part of an experimental Auto routing surface and may change
1630
+ * or be removed in a future release.
1631
+ *
1632
+ * @example
1633
+ * ```typescript
1634
+ * const result = await session.setAutoTier("intelligence");
1635
+ * if (result.status === "pending") {
1636
+ * // Takes effect on a later turn that uses the `auto` model.
1637
+ * }
1638
+ * ```
1639
+ */
1640
+ async setAutoTier(autoTier) {
1641
+ return await this.rpc.model.switchAutoTier({ autoTier });
1642
+ }
1545
1643
  /**
1546
1644
  * Log a message to the session timeline.
1547
1645
  * The message appears in the session event stream and is visible to SDK consumers
package/dist/types.d.ts CHANGED
@@ -4,7 +4,7 @@
4
4
  import type { Canvas } from "./canvas.js";
5
5
  import type { SessionFsProvider } from "./sessionFsProvider.js";
6
6
  import type { CopilotRequestHandler } from "./copilotRequestHandler.js";
7
- import type { PermissionRequest as GeneratedPermissionRequest, PermissionRequestedData as GeneratedPermissionRequestedData, PermissionRequestedEvent as GeneratedPermissionRequestedEvent, ReasoningSummary, SessionLimitsConfig, SessionEvent as GeneratedSessionEvent } from "./generated/session-events.js";
7
+ import type { AutoTier, PermissionRequest as GeneratedPermissionRequest, PermissionRequestedData as GeneratedPermissionRequestedData, PermissionRequestedEvent as GeneratedPermissionRequestedEvent, ReasoningSummary, SessionLimitsConfig, SessionEvent as GeneratedSessionEvent } from "./generated/session-events.js";
8
8
  import type { CopilotSession } from "./session.js";
9
9
  import type { FactoryJsonSchema, JsonValue } from "./factory.js";
10
10
  import type { GitHubTokenAcquireRequest, GitHubTokenAcquireResult, GitHubTelemetryNotification, ModelBillingTokenPrices, OpenCanvasInstance, RemoteSessionMode, CurrentToolMetadata } from "./generated/rpc.js";
@@ -34,7 +34,8 @@ export type { ModelBillingTokenPrices, ModelBillingTokenPricesLongContext, } fro
34
34
  export type SessionEvent = Exclude<GeneratedSessionEvent, {
35
35
  type: "permission.requested";
36
36
  }> | PermissionRequestedEvent;
37
- export type { ReasoningSummary } from "./generated/session-events.js";
37
+ export type { AutoTier, ReasoningSummary } from "./generated/session-events.js";
38
+ export type { CurrentModel, ModelSwitchAutoTierResult, ModelSwitchAutoTierStatus, } from "./generated/rpc.js";
38
39
  export type { SessionFsProvider } from "./sessionFsProvider.js";
39
40
  export { createSessionFsAdapter } from "./sessionFsProvider.js";
40
41
  export type { SessionFsFileInfo } from "./sessionFsProvider.js";
@@ -216,6 +217,33 @@ export declare const RuntimeConnection: {
216
217
  * ambient behavior is unsafe (e.g. multi-user servers).
217
218
  */
218
219
  export type CopilotClientMode = "empty" | "copilot-cli";
220
+ /**
221
+ * Identity of the integrating application, declared once on the `server.connect`
222
+ * handshake so the telemetry the runtime emits on this connection is attributed
223
+ * to a single, consistent surface rather than to the runtime's own build.
224
+ *
225
+ * All fields are optional; omit any of them (or the whole object) to keep the
226
+ * runtime's default attribution. Version fields are ignored by the runtime
227
+ * unless they look like a version string.
228
+ */
229
+ export interface CopilotClientInfo {
230
+ /**
231
+ * Name of the application using the SDK, e.g. `"acme-developer-portal"`.
232
+ */
233
+ applicationName?: string;
234
+ /**
235
+ * Version of the application using the SDK, e.g. `"2.4.0"`.
236
+ */
237
+ applicationVersion?: string;
238
+ /**
239
+ * Optional name of a specific integration within the application, such as an extension or plugin.
240
+ */
241
+ integrationName?: string;
242
+ /**
243
+ * Optional version of the integration identified by `integrationName`.
244
+ */
245
+ integrationVersion?: string;
246
+ }
219
247
  export interface CopilotClientOptions {
220
248
  /**
221
249
  * How to connect to the Copilot runtime. When omitted, defaults to
@@ -370,6 +398,15 @@ export interface CopilotClientOptions {
370
398
  * @default false
371
399
  */
372
400
  enableRemoteSessions?: boolean;
401
+ /**
402
+ * Identity of the integrating application, forwarded to the runtime on the
403
+ * `server.connect` handshake. Declaring it lets the telemetry the runtime
404
+ * emits on this connection be attributed to a single, consistent surface
405
+ * (e.g. the application and its Copilot integration) instead of the
406
+ * runtime's own build. All fields are optional; omit it to keep the default
407
+ * attribution.
408
+ */
409
+ clientInfo?: CopilotClientInfo;
373
410
  }
374
411
  /**
375
412
  * Configuration for creating a session
@@ -460,6 +497,8 @@ export interface ToolInvocation {
460
497
  traceparent?: string;
461
498
  /** W3C Trace Context tracestate from the CLI's execute_tool span. */
462
499
  tracestate?: string;
500
+ /** Aborted when the runtime completes this request or the session disconnects. */
501
+ signal?: AbortSignal;
463
502
  }
464
503
  export type ToolHandler<TArgs = unknown> = (args: TArgs, invocation: ToolInvocation) => Promise<unknown> | unknown;
465
504
  /**
@@ -1705,6 +1744,20 @@ export interface FactoryMeta {
1705
1744
  * provider-level choices are conceptually per-provider rather than global.
1706
1745
  */
1707
1746
  export interface CapiSessionOptions {
1747
+ /**
1748
+ * Routing preference used when the session model is `auto`.
1749
+ * Requires a runtime with Auto tier support and V2 Auto routing.
1750
+ *
1751
+ * When omitted on create, the runtime uses its default routing behavior.
1752
+ * The runtime persists this preference across cold resume; when omitted on
1753
+ * cold resume, it restores the last committed preference. On resident
1754
+ * resume, a different tier requests a safe switch that takes effect after
1755
+ * resume succeeds, and never disturbs a turn that is already running.
1756
+ *
1757
+ * To change the preference on a live session, call
1758
+ * {@link CopilotSession.setAutoTier} instead.
1759
+ */
1760
+ autoTier?: AutoTier;
1708
1761
  /**
1709
1762
  * Whether to use the WebSocket transport for the CAPI Responses API.
1710
1763
  *
@@ -2375,6 +2428,11 @@ export interface SessionConfigBase {
2375
2428
  * only if {@link CopilotClientOptions.sessionFs} is configured.
2376
2429
  */
2377
2430
  createSessionFsProvider?: (session: CopilotSession) => SessionFsProvider;
2431
+ /**
2432
+ * Feature-flag values resolved by the host for this session.
2433
+ * Re-supply them when resuming after a runtime restart.
2434
+ */
2435
+ featureFlags?: Record<string, boolean>;
2378
2436
  }
2379
2437
  /**
2380
2438
  * Configuration for creating a new session via {@link CopilotClient.createSession}.